play.api.mvc.RequestHeader Scala Examples

The following examples show how to use play.api.mvc.RequestHeader. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: AuthFilter.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package filters

import akka.stream.Materializer
import play.api.libs.json.Json
import play.api.mvc.{Filter, RequestHeader, Result, Results}
import security.PermissionLevel._
import security._
import wsutil._
import javax.inject._
import cmwell.ws.Settings

import scala.concurrent.{ExecutionContext, Future}

class AuthFilter @Inject()(authCache: EagerAuthCache, authUtils: AuthUtils, authorization: Authorization)(
  implicit override val mat: Materializer,
  ec: ExecutionContext
) extends Filter {

  private val useAuthorizationParam = java.lang.Boolean.getBoolean("use.authorization")
  private val irrelevantPaths = Set("/ii/", "/_")

  def apply(nextFilter: RequestHeader => Future[Result])(requestHeader: RequestHeader): Future[Result] = {
    isAuthenticatedAndAuthorized(requestHeader) match {
      case Allowed(username) =>
        nextFilter(requestHeader.addAttr(Attrs.UserName, username))
      case NotAllowed(msg) if PermissionLevel(requestHeader.method) == PermissionLevel.Read =>
        Future(Results.Forbidden(msg))
      case NotAllowed(msg) =>
        Future(Results.Forbidden(Json.obj("success" -> false, "message" -> msg)))
    }
  }

  private def isAuthenticatedAndAuthorized(requestHeader: RequestHeader): AuthResponse = {
    def isRequestWriteToMeta = authUtils.isWriteToMeta(PermissionLevel(requestHeader.method), requestHeader.path)

    val tokenOpt = requestHeader.headers
      .get("X-CM-WELL-TOKEN2")
      . // todo TOKEN2 is only supported for backward compatibility. one day we should stop supporting it
      orElse(requestHeader.headers.get("X-CM-WELL-TOKEN"))
      .orElse(requestHeader.getQueryString("token"))
      .orElse(requestHeader.cookies.get("X-CM-WELL-TOKEN2").map(_.value))
      . // todo TOKEN2 is only supported for backward compatibility. one day we should stop supporting it
      orElse(requestHeader.cookies.get("X-CM-WELL-TOKEN").map(_.value))
      .flatMap(Token(_, authCache))

    val modifier = tokenOpt.fold("anonymous")(_.username) + requestHeader.getQueryString("modifier").fold("")("/".+)

    if ((!useAuthorizationParam && !isRequestWriteToMeta) || irrelevantPaths.exists(requestHeader.path.startsWith))
      Allowed(modifier)
    else {
      val request =
        (normalizePath(requestHeader.path), PermissionLevel(requestHeader.method, requestHeader.getQueryString("op")))

      tokenOpt match {
        case Some(token) if token.isValid => {
          authCache.getUserInfoton(token.username) match {
            case Some(user) =>
              AuthResponse(authorization.isAllowedForUser(request, user, Some(token.username)),
                "Authenticated but not authorized", modifier)
            case None if token.username == "root" || token.username == "pUser" =>
              Allowed(modifier) // special case only required for cases when CRUD is not yet ready
            case None => NotAllowed(s"Username ${token.username} was not found in CM-Well")
          }
        }
        case Some(_) => NotAllowed("given token is not valid (not signed or expired)")
        case None => AuthResponse(authorization.isAllowedForAnonymousUser(request), "Not authorized, please login first", modifier)
      }
    }
  }

  sealed trait AuthResponse
  case class Allowed(modifier: String) extends AuthResponse
  case class NotAllowed(msg: String) extends AuthResponse

  object AuthResponse {
    def apply(allowed: Boolean, msg: String, modifier: String): AuthResponse =
      if(allowed) Allowed(modifier) else NotAllowed(msg)
  }
} 
Example 2
Source File: ErrorHandler.scala    From asura   with MIT License 5 votes vote down vote up
package asura.play.hook

import asura.common.exceptions.ErrorMessages
import asura.common.exceptions.ErrorMessages.ErrorMessageException
import asura.common.model.{ApiCode, ApiRes, ApiResError}
import asura.common.util.{LogUtils, StringUtils}
import asura.play.api.BaseApi.OkApiRes
import javax.inject.{Inject, Singleton}
import org.slf4j.LoggerFactory
import play.api.http.HttpErrorHandler
import play.api.i18n.{Langs, MessagesApi}
import play.api.mvc.{RequestHeader, Result}

import scala.concurrent.Future

@Singleton
class ErrorHandler @Inject()(messagesApi: MessagesApi, langs: Langs) extends HttpErrorHandler with ErrorMessages {

  lazy val logger = LoggerFactory.getLogger(classOf[ErrorHandler])

  override def onClientError(request: RequestHeader, statusCode: Int, message: String): Future[Result] = {
    val msg = s""""${request.method} ${request.uri}" ${statusCode} ${if (StringUtils.isNotEmpty(message)) message else ""}"""
    Future.successful(OkApiRes(ApiResError(msg)))
  }

  override def onServerError(request: RequestHeader, exception: Throwable): Future[Result] = {
    val logStack = LogUtils.stackTraceToString(exception)
    logger.warn(logStack)
    val requestLocal = request.headers.get("Local")
    implicit val lang = if (requestLocal.nonEmpty) {
      langs.availables.find(_.code == requestLocal.get).getOrElse(langs.availables.head)
    } else {
      langs.availables.head
    }
    exception match {
      case errMsgException: ErrorMessageException =>
        val errMsg = messagesApi(errMsgException.error.name, errMsgException.error.errMsg)
        Future.successful(OkApiRes(ApiRes(code = ApiCode.ERROR, msg = errMsg, data = logStack)))
      case _ =>
        val message = if (StringUtils.isNotEmpty(exception.getMessage)) {
          exception.getMessage
        } else {
          messagesApi(error_ServerError.name)
        }
        Future.successful(OkApiRes(ApiRes(code = ApiCode.ERROR, msg = message, data = logStack)))
    }
  }
} 
Example 3
Source File: AuthCtrlSpec.scala    From gospeak   with Apache License 2.0 5 votes vote down vote up
package gospeak.web.auth

import gospeak.core.domain.User
import gospeak.core.testingutils.Generators._
import gospeak.libs.scala.domain.{EmailAddress, Secret}
import gospeak.web.testingutils.CtrlSpec
import gospeak.web.utils.GsForms.SignupData
import org.scalatest.BeforeAndAfterEach
import play.api.http.Status
import play.api.mvc.{AnyContentAsFormUrlEncoded, RequestHeader, Result}
import play.api.test.Helpers._

import scala.concurrent.Future

class AuthCtrlSpec extends CtrlSpec with BeforeAndAfterEach {
  private val _ = aEmailAddress // to keep the `gospeak.core.testingutils.Generators._` import
  private val ctrl = new AuthCtrl(cc, silhouette, conf, db.user, db.userRequest, db.group, authSrv, emailSrv)
  private val redirect: Option[String] = None
  // private val signupData = random[SignupData] // TODO add generators constraints: firstName&lastName should not be empty, password should have 8 char at least
  private val signupData = SignupData(User.Slug.from("slug").right.get, "first", "last", EmailAddress.from("[email protected]").right.get, Secret("passpass"), rememberMe = true)

  override def beforeEach(): Unit = {
    db.migrate().unsafeRunSync()
    emailSrv.sentEmails.clear()
  }

  override def afterEach(): Unit = db.dropTables().unsafeRunSync()

  describe("AuthCtrl") {
    describe("signup") {
      it("should return form when not authenticated") {
        val res = ctrl.signup(redirect).apply(unsecuredReq)
        status(res) shouldBe Status.OK
      }
      it("should redirect to user home when authenticated") {
        val res = ctrl.signup(redirect).apply(securedReq)
        status(res) shouldBe Status.SEE_OTHER
      }
      it("should create a user and credentials then login") {
        val res = AuthCtrlSpec.doSignup(signupData)(unsecuredReq)(ctrl)
        contentAsString(res) shouldBe ""
        headers(res) should contain key "Location"
        status(res) shouldBe Status.SEE_OTHER
        emailSrv.sentEmails should have length 1
      }
      it("should find the user, create credentials then login") {

      }
      it("should fail if credentials already exist") {

      }
    }
    describe("login") {
      it("should return form when not authenticated") {
        val res = ctrl.login(redirect).apply(unsecuredReq)
        status(res) shouldBe Status.OK
      }
      it("should redirect to user home when authenticated") {
        val res = ctrl.login(redirect).apply(securedReq)
        status(res) shouldBe Status.SEE_OTHER
      }
    }
    describe("forgotPassword") {
      it("should return form when not authenticated") {
        val res = ctrl.forgotPassword(redirect).apply(unsecuredReq)
        status(res) shouldBe Status.OK
      }
      it("should redirect to user home when authenticated") {
        val res = ctrl.forgotPassword(redirect).apply(securedReq)
        status(res) shouldBe Status.SEE_OTHER
      }
    }
  }
}

object AuthCtrlSpec {
  def doSignup(data: SignupData, redirect: Option[String] = None)(req: RequestHeader)(ctrl: AuthCtrl): Future[Result] = {
    ctrl.doSignup(redirect).apply(req.withBody(AnyContentAsFormUrlEncoded(Map(
      "slug" -> Seq(data.slug.value),
      "first-name" -> Seq(data.firstName),
      "last-name" -> Seq(data.lastName),
      "email" -> Seq(data.email.value),
      "password" -> Seq(data.password.decode),
      "rememberMe" -> Seq(data.rememberMe.toString)
    ))))
  }
} 
Example 4
Source File: CustomSecuredErrorHandler.scala    From gospeak   with Apache License 2.0 5 votes vote down vote up
package gospeak.web.auth.services

import com.mohiva.play.silhouette.api.actions.SecuredErrorHandler
import gospeak.web.api.domain.utils.ErrorResult
import gospeak.web.auth.routes.AuthCtrl
import gospeak.web.pages.user.routes.UserCtrl
import gospeak.web.utils.HttpUtils
import play.api.http.Status
import play.api.i18n.{I18nSupport, MessagesApi}
import play.api.libs.json.Json
import play.api.mvc.Results._
import play.api.mvc.{RequestHeader, Result}

import scala.concurrent.Future

class CustomSecuredErrorHandler(val messagesApi: MessagesApi) extends SecuredErrorHandler with I18nSupport {
  override def onNotAuthenticated(implicit req: RequestHeader): Future[Result] = {
    val message = "Unauthorized: please login"
    if (req.uri.startsWith("/api")) {
      Future.successful(Unauthorized(Json.toJson(ErrorResult(Status.UNAUTHORIZED, message, execMs = 0))))
    } else {
      Future.successful(Redirect(AuthCtrl.login(Some(req.uri))).flashing("warning" -> message))
    }
  }

  override def onNotAuthorized(implicit req: RequestHeader): Future[Result] = {
    val message = "Forbidden: it seems you lack some rights here"
    if (req.uri.startsWith("/api")) {
      Future.successful(Unauthorized(Json.toJson(ErrorResult(Status.FORBIDDEN, message, execMs = 0))))
    } else {
      val next = Redirect(HttpUtils.getReferer(req.headers).getOrElse(UserCtrl.index().path()))
      Future.successful(next.flashing("error" -> message))
    }
  }
} 
Example 5
Source File: AccessLoggingFilter.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package filters

import akka.stream.Materializer
import javax.inject.Inject
import org.slf4j.LoggerFactory
import play.api.mvc.{Filter, RequestHeader, Result}
import play.mvc.Http

import scala.concurrent.{ExecutionContext, Future}

class AccessLoggingFilter @Inject() (
    implicit val mat: Materializer,
    executionContext: ExecutionContext
) extends Filter {

  private val logger = LoggerFactory.getLogger(classOf[AccessLoggingFilter])

  def apply(next: RequestHeader => Future[Result])(request: RequestHeader): Future[Result] = {
    val resultFuture = next(request)

    resultFuture.foreach(result => {
      if (!request.uri.contains("/public") && !request.uri.contains("/assets")) {
        val msg = s"Request: method=${request.method}, path=${request.uri}, " +
          s"remote_address=${request.remoteAddress}, " +
          s"user_agent=${request.headers.get(Http.HeaderNames.USER_AGENT).getOrElse("unknown")} " +
          s"| Response: status_code=${result.header.status} "
        logger.info(msg)
      }
    })

    resultFuture
  }
} 
Example 6
Source File: ErrorHandler.scala    From DataQuality   with GNU Lesser General Public License v3.0 5 votes vote down vote up
package org.openapitools

import play.api.http.DefaultHttpErrorHandler
import play.api.libs.json.JsResultException
import play.api.mvc.Results._
import play.api.mvc.{RequestHeader, Result}

import scala.concurrent.Future

class ErrorHandler extends DefaultHttpErrorHandler {
  override def onServerError(request: RequestHeader, e: Throwable): Future[Result] = e match {
    case _: OpenApiExceptions.MissingRequiredParameterException =>
      Future.successful(BadRequest(e.getMessage))
    case _: JsResultException =>
      Future.successful(BadRequest(e.getMessage))
    case _ =>
      // Handles dev mode properly, or otherwise returns internal server error in production mode
      super.onServerError(request, e)
  }
} 
Example 7
Source File: AuthConfigImpl.scala    From bay-scalajs.g8   with Apache License 2.0 5 votes vote down vote up
package controllers

import jp.t2v.lab.play2.auth._
import play.api.mvc.RequestHeader
import play.api.mvc.Result
import services.Services
import services.dao.UserDao

import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.reflect._

trait AuthConfigImpl extends AuthConfig with ExtendedController {

  val services: Services

  type Id        = Int
  type User      = shared.models.slick.default.User
  type Authority = User => Future[Boolean]
  val idTag: ClassTag[Id]          = classTag[Id]
  val sessionTimeoutInSeconds: Int = 3600

  def resolveUser(id: Id)(implicit ctx: ExecutionContext): Future[Option[User]] =
    services.userDao.resolveUser(id)(ctx)

  def loginSucceeded(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] =
    Redirect(routes.Application.index("")).asFuture

  def logoutSucceeded(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] =
    Redirect(routes.Application.index("")).asFuture

  def authenticationFailed(request: RequestHeader)(
      implicit ctx: ExecutionContext): Future[Result] = Unauthorized.asFuture

  override def authorizationFailed(
      request: RequestHeader,
      user: User,
      authority: Option[Authority])(implicit context: ExecutionContext): Future[Result] =
    Unauthorized.asFuture

  def authorize(user: User, authority: Authority)(
      implicit ctx: ExecutionContext): Future[Boolean] = authority(user)

  // Define reusable authorities

  def isLoggedIn(user: User): Future[Boolean] = true.asFuture

  def isInGroup(groupName: String)(user: User): Future[Boolean] =
    services.userDao.isInGroup(user.id, groupName)
} 
Example 8
Source File: CMWellRequest.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package cmwell.ws.adt.request

import play.api.mvc.RequestHeader
import cmwell.ws.util.RequestHelpers.cmWellBase

sealed trait CMWellRequest {

  protected def requestHeader: RequestHeader
  protected[this] def queryParams: Map[String, Seq[String]]

  lazy val path: String = wsutil.normalizePath(requestHeader.path)

  // order of ++ is important. we want to give precedence to parameters in payload
  // and only take defaults from query params if payload don't have it.
  // i.e: keys in `queryParams` will override same keys in `requestHeader.queryString`
  lazy val queryParameters: Map[String, Seq[String]] = requestHeader.queryString ++ queryParams
}

final class CreateConsumer private (protected override val requestHeader: RequestHeader,
                                    protected[this] override val queryParams: Map[String, Seq[String]])
    extends CMWellRequest
object CreateConsumer {
  def apply(rh: RequestHeader, qp: Map[String, Seq[String]]) = new CreateConsumer(rh, qp)
  def unapply(cc: CreateConsumer) = Some((cc.path, cc.queryParameters))
}

final class Search private (protected override val requestHeader: RequestHeader,
                            protected[this] override val queryParams: Map[String, Seq[String]])
    extends CMWellRequest {
  private lazy val base = cmWellBase(requestHeader)
  private lazy val host = requestHeader.host
  private lazy val uri = requestHeader.uri
}
object Search {
  def apply(rh: RequestHeader, qp: Map[String, Seq[String]]) = new Search(rh, qp)
  def unapply(s: Search) = Some((s.path, s.base, s.host, s.uri, s.queryParameters))
} 
Example 9
Source File: AddCharsetIfNotExistFilter.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package filters

import javax.inject._

import akka.stream.Materializer
import controllers.XCmWellType
import play.api.http.HeaderNames
import play.api.mvc.{Filter, Headers, RequestHeader, Result}
import scala.concurrent.Future

class AddCharsetIfNotExistFilter @Inject()(implicit override val mat: Materializer) extends Filter {
  def apply(next: (RequestHeader) => Future[Result])(request: RequestHeader): Future[Result] = request match {
    case XCmWellType.File()             => next(request)
    case _ if request.charset.isDefined => next(request)
    case _ => {
      val charset = request.charset.getOrElse("UTF-8")
      val contentType = request.contentType.getOrElse("text/plain")

      val headers = request.headers.headers.filterNot(_._1 == HeaderNames.CONTENT_TYPE) ++ Seq(
        HeaderNames.CONTENT_TYPE -> s"$contentType;charset=$charset"
      )
      val modifiedRequestHeader = request.withHeaders(Headers(headers: _*))

      next(modifiedRequestHeader)
    }
  }
} 
Example 10
Source File: TrafficShapingFilter.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package filters

import javax.inject._

import akka.stream.Materializer
import play.api.mvc.{Filter, RequestHeader, Result, Results}

import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.duration._
import scala.util.{Success, Try}
import cmwell.ws.Settings._
import trafficshaping._


class TrafficShapingFilter @Inject()(implicit override val mat: Materializer, ec: ExecutionContext) extends Filter {

  def reqType(req: RequestHeader): String = {
    val opOpt = req.getQueryString("op")
    val segs = req.path.split("/")
    val path = Try(req.path.split("/")(1))

    (opOpt, path) match {
      case (Some(op), _)                           => op
      case (None, Success(p)) if p.startsWith("_") => p
      case _                                       => "get"
    }
  }

  def collectData(resultFuture: Future[Result], ip: String, requestType: String, startTime: Long): Unit = {
    if (ip != "127.0.0.1") {
      resultFuture.foreach { r =>
        val requestDuration = System.currentTimeMillis() - startTime
        TrafficShaper.addRequest(ip, requestType, requestDuration)
      }

    }
  }

  def collectData(ip: String, requestType: String, startTime: Long): Unit = {
    if (ip != "127.0.0.1") {
      val requestDuration = System.currentTimeMillis() - startTime
      TrafficShaper.addRequest(ip, requestType, requestDuration)
    }
  }

  def isNeedTrafficShapping(ip: String, requestType: String): Boolean = {
    val untrackedRequests = Vector("_in", "_ow")
    !untrackedRequests.contains(requestType)
  }

  override def apply(next: (RequestHeader) => Future[Result])(request: RequestHeader): Future[Result] = {
    import Math._

    val ip = request.attrs(Attrs.UserIP)
    lazy val resultFuture = next(request)
    val startTime = request.attrs(Attrs.RequestReceivedTimestamp)
    val maxDurationMillis = maxRequestTimeSec * 1000
    val penalty = TrafficShaper.penalty(ip)
    val requestType = reqType(request)

    if (TrafficShaper.isEnabled && isNeedTrafficShapping(ip, requestType))
      penalty match {
        case NoPenalty =>
          collectData(resultFuture, ip, requestType, startTime)
          resultFuture
        case DelayPenalty =>
          collectData(resultFuture, ip, requestType, startTime)
          resultFuture.flatMap { res =>
            val currentTime = System.currentTimeMillis()
            val reqDurationMillis = currentTime - startTime
            val penalty = min(reqDurationMillis, maxDurationMillis - reqDurationMillis).max(0)
            cmwell.util.concurrent.delayedTask(penalty.millis) { res }
          }
        case FullBlockPenalty =>
          cmwell.util.concurrent.delayedTask(maxDurationMillis.millis) {
            collectData(ip, requestType, startTime)
            Results.ServiceUnavailable("Please reduce the amount of requests")
          }
      } else
      resultFuture
  }
} 
Example 11
Source File: ClusterApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import akka.actor.ActorSystem
import akka.pattern.ask
import akka.util.Timeout
import asura.app.AppErrorMessages
import asura.cluster.ClusterManager
import asura.cluster.actor.MemberListenerActor.GetAllMembers
import asura.common.model.ApiResError
import asura.core.CoreConfig
import asura.play.api.BaseApi.OkApiRes
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents
import play.api.Configuration
import play.api.mvc.{RequestHeader, Result}

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class ClusterApi @Inject()(
                            implicit val system: ActorSystem,
                            val exec: ExecutionContext,
                            val configuration: Configuration,
                            val controllerComponents: SecurityComponents
                          ) extends BaseApi {

  implicit val timeout: Timeout = CoreConfig.DEFAULT_ACTOR_ASK_TIMEOUT

  def getMembers() = Action(parse.byteString).async { implicit req =>
    checkClusterEnabled {
      (ClusterManager.clusterManagerActor ? GetAllMembers).toOkResult
    }
  }

  private def checkClusterEnabled(func: => Future[Result])(implicit request: RequestHeader): Future[Result] = {
    if (ClusterManager.enabled) {
      func
    } else {
      Future.successful(OkApiRes(ApiResError(getI18nMessage(AppErrorMessages.error_ClusterNotEnabled))))
    }
  }
} 
Example 12
Source File: AddFormatParameterIfOnlyAcceptHeaderProvidedFilter.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package filters

import akka.stream.Materializer
import com.typesafe.scalalogging.LazyLogging
import javax.inject._
import play.api.http.MediaType
import play.api.mvc.{Filter, RequestHeader, Result}

import scala.concurrent.Future

class AddFormatParameterIfOnlyAcceptHeaderProvidedFilter @Inject()(implicit val mat: Materializer) extends Filter {
  //MediaType2Format
  private[this] val mt2f: PartialFunction[String, PartialFunction[String, String]] = (mt: String) =>
    mt match {
      case "text" => {
        case "yaml"       => "yaml"
        case "json"       => "json"
        case "rdf+n3"     => "n3"
        case "n3"         => "n3"
        case "plain"      => "ntriples"
        case "ntriples"   => "ntriples"
        case "turtle"     => "ttl"
        case "ttl"        => "ttl"
        case "rdf+turtle" => "ttl"
        case "rdf+ttl"    => "ttl"
        case "n-quads"    => "nquads"
      }
      case "application" => {
        case "json"     => "jsonl"
        case "ld+json"  => "jsonld"
        case "rdf+xml"  => "rdfxml"
        case "x-nquads" => "nquads"
      }
      //    case "xml" => {
      //      case "rdf" => "rdfxml"
      //    }
  }

  private def formatToValidType(mt: MediaType): String = mt2f(mt.mediaType)(mt.mediaSubType)

  private def isCMWellAccepted(mt: MediaType): Boolean =
    mt2f.isDefinedAt(mt.mediaType) && mt2f(mt.mediaType).isDefinedAt(mt.mediaSubType)

  override def apply(next: (RequestHeader) => Future[Result])(request: RequestHeader): Future[Result] = {
    val withFormat =
      if ((request.getQueryString("format").isDefined || request.acceptedTypes.isEmpty) && Set("post", "get")(
            request.method.toLowerCase
          )) request
      else
        request.acceptedTypes.find(isCMWellAccepted(_)) match {
          case Some(mt) =>
            val newTarget = request.target.withQueryString(request.target.queryMap + ("format" -> Seq(formatToValidType(mt))))
            request.withTarget(newTarget)
          case None     => request
        }
    next(withFormat)
  }
} 
Example 13
Source File: TypeHelpers.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package cmwell.ws.util

import java.net.InetAddress
import cmwell.ws.Settings
import play.api.mvc.{Request, RequestHeader}
import play.api.http.HeaderNames


trait TypeHelpers {

  def asInt(number: String): Option[Int] = {
    //require(limit > 0, "must be positive!")
    try {
      val s = number.trim.dropWhile(_ == '0')
      require(s.forall(_.isDigit), s"Not a valid positive number format: $s")
      require(s.length < 10 || (s.length == 10 && s <= "2147483647"), s"the number $s seems to be too big") //don't try to parse something larger than MAX_INT
      Some(s.toInt)
    } catch {
      case _: NumberFormatException | _: NullPointerException => None
      case t: Throwable                                       => throw t
    }
  }

  def asLong(number: String): Option[Long] = {
    //require(limit > 0, "must be positive!")
    try {
      val s = number.trim.dropWhile(_ == '0')
      require(s.forall(_.isDigit), s"Not a valid positive number format: $s")
      //don't try to parse something larger than MAX_LONG
      require(s.length < 19 || (s.length == 19 && s <= "9223372036854775807"), s"the number $s seems to be too big")
      Some(s.toLong)
    } catch {
      case _: NumberFormatException | _: NullPointerException => None
      case t: Throwable                                       => throw t
    }
  }

  def asBoolean(s: String): Option[Boolean] = {
    if (null eq s) None
    else
      s.toLowerCase match {
        case "" | "t" | "true" | "yes" | "1" => Some(true)
        case "f" | "false" | "no" | "0"      => Some(false)
        case _                               => None
      }
  }

}

object TypeHelpers extends TypeHelpers

object RequestHelpers {

  def cmWellBase(implicit req: RequestHeader): String = {
    "http://" + req.headers
      .get(HeaderNames.HOST)
      .getOrElse(
        InetAddress.getLocalHost().getHostName() + Option(System.getProperty("application.port"))
          .map(":" + _)
          .getOrElse("")
      )
  }
} 
Example 14
Source File: LoggingFilter.scala    From HAT2.0   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.hatdex.hat.utils

import javax.inject.{ Inject, Singleton }
import akka.stream.Materializer
import com.nimbusds.jose.JWSObject
import com.nimbusds.jwt.JWTClaimsSet
import play.api.http.HttpErrorHandler
import play.api.mvc.{ Filter, RequestHeader, Result }
import play.api.{ Configuration, Logger }

import scala.concurrent.{ ExecutionContext, Future }
import scala.util.Try

@Singleton
class ActiveHatCounter() {
  // Careful! Mutable state
  private var count: Long = 0

  def get(): Long = count
  def increase(): Unit = this.synchronized(count += 1)
  def decrease(): Unit = this.synchronized(count -= 1)
}

class LoggingFilter @Inject() (
    errorHandler: HttpErrorHandler,
    configuration: Configuration,
    hatCounter: ActiveHatCounter)(
    implicit
    ec: ExecutionContext,
    val mat: Materializer) extends Filter {
  private val logger = Logger("api")

  def apply(nextFilter: RequestHeader => Future[Result])(requestHeader: RequestHeader): Future[Result] = {

    val startTime = System.currentTimeMillis

    nextFilter(requestHeader)
      .recoverWith({
        case e ⇒ errorHandler.onServerError(requestHeader, e)
      })
      .map { result =>
        val active = hatCounter.get()
        val requestTime = System.currentTimeMillis - startTime
        logger.info(s"[${requestHeader.remoteAddress}] [${requestHeader.method}:${requestHeader.host}:${requestHeader.uri}] " +
          s"[${result.header.status}] [$requestTime:ms] [hats:$active] ${tokenInfo(requestHeader)}")

        result.withHeaders("Request-Time" -> requestTime.toString)
      }
  }

  private val authTokenFieldName: String = configuration.get[String]("silhouette.authenticator.fieldName")
  private def tokenInfo(requestHeader: RequestHeader): String = {
    requestHeader.queryString.get(authTokenFieldName).flatMap(_.headOption)
      .orElse(requestHeader.headers.get(authTokenFieldName))
      .flatMap(t ⇒ if (t.isEmpty) { None } else { Some(t) })
      .flatMap(t ⇒ Try(JWSObject.parse(t)).toOption)
      .map(o ⇒ JWTClaimsSet.parse(o.getPayload.toJSONObject))
      .map { claimSet =>
        s"[${Option(claimSet.getStringClaim("application")).getOrElse("api")}@" +
          s"${Option(claimSet.getStringClaim("applicationVersion")).getOrElse("_")}]"
      }
      .getOrElse("[unauthenticated@_]")
  }
} 
Example 15
Source File: Mailer.scala    From HAT2.0   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.hatdex.hat.utils

import javax.inject.Inject
import akka.Done
import akka.actor.ActorSystem
import org.hatdex.hat.api.service.RemoteExecutionContext
import org.hatdex.hat.authentication.models.HatUser
import org.hatdex.hat.phata.views
import org.hatdex.hat.resourceManagement.HatServer
import play.api.i18n.{ Lang, Messages, MessagesApi }
import play.api.libs.mailer.{ Email, MailerClient }
import play.api.mvc.RequestHeader
import play.api.{ Configuration, UsefulException }
import play.twirl.api.Html

import scala.concurrent.{ ExecutionContext, Future }

trait Mailer {
  protected val configuration: Configuration
  protected val system: ActorSystem
  protected val mailerClient: MailerClient

  import scala.language.implicitConversions

  implicit def html2String(html: Html): String = html.toString

  def serverErrorNotify(request: RequestHeader, exception: UsefulException)(implicit m: Messages): Done

  def serverExceptionNotify(request: RequestHeader, exception: Throwable)(implicit m: Messages): Done

  def sendEmail(recipients: String*)(from: String, subject: String, bodyHtml: String, bodyText: String)(implicit ec: ExecutionContext): Future[Done] = {
    Future(mailerClient.send(Email(subject, from, recipients, Some(bodyText), Some(bodyHtml))))
      .map(_ => Done)
  }
}

trait HatMailer extends Mailer {
  def serverErrorNotify(request: RequestHeader, exception: UsefulException)(implicit m: Messages): Done
  def serverExceptionNotify(request: RequestHeader, exception: Throwable)(implicit m: Messages): Done
  def passwordReset(email: String, user: HatUser, resetLink: String)(implicit m: Messages, server: HatServer): Done
  def passwordChanged(email: String, user: HatUser)(implicit m: Messages, server: HatServer): Done

  def claimHat(email: String, claimLink: String, maybePartnerDetails: Option[(String, String)])(implicit m: MessagesApi, l: Lang, server: HatServer): Done
}

class HatMailerImpl @Inject() (
    val configuration: Configuration,
    val system: ActorSystem,
    val mailerClient: MailerClient)(implicit ec: RemoteExecutionContext) extends HatMailer {
  private val emailFrom = configuration.get[String]("play.mailer.from")
  private val adminEmails = configuration.get[Seq[String]]("exchange.admin")

  def serverErrorNotify(request: RequestHeader, exception: UsefulException)(implicit m: Messages): Done = {
    sendEmail(adminEmails: _*)(
      from = emailFrom,
      subject = s"HAT server ${request.host} error #${exception.id}",
      bodyHtml = views.html.mails.emailServerError(request, exception),
      bodyText = views.html.mails.emailServerError(request, exception).toString())
    Done
  }

  def serverExceptionNotify(request: RequestHeader, exception: Throwable)(implicit m: Messages): Done = {
    sendEmail(adminEmails: _*)(
      from = emailFrom,
      subject = s"HAT server ${request.host} error: ${exception.getMessage} for ${request.path + request.rawQueryString}",
      bodyHtml = views.html.mails.emailServerThrowable(request, exception),
      bodyText = views.html.mails.emailServerThrowable(request, exception).toString())
    Done
  }

  def passwordReset(email: String, user: HatUser, resetLink: String)(implicit m: Messages, server: HatServer): Done = {
    sendEmail(email)(
      from = emailFrom,
      subject = s"HAT ${server.domain} - reset your password",
      bodyHtml = views.html.mails.emailPasswordReset(user, server.domain, resetLink),
      bodyText = views.txt.mails.emailPasswordReset(user, server.domain, resetLink).toString())
    Done
  }

  def passwordChanged(email: String, user: HatUser)(implicit m: Messages, server: HatServer): Done = {
    sendEmail(email)(
      from = emailFrom,
      subject = s"HAT ${server.domain} - password changed",
      bodyHtml = views.html.mails.emailPasswordChanged(user, server.domain),
      bodyText = views.txt.mails.emailPasswordChanged(user, server.domain).toString())
    Done
  }

  def claimHat(email: String, claimLink: String, maybePartnerDetails: Option[(String, String)])(implicit m: MessagesApi, l: Lang, server: HatServer): Done = {
    sendEmail(email)(
      from = "[email protected]",
      subject = m("email.hatclaim.subject", maybePartnerDetails.map(_._1).getOrElse("")),
      bodyHtml = views.html.mails.emailHatClaim(server.domain, claimLink, maybePartnerDetails),
      bodyText = views.txt.mails.emailHatClaim(server.domain, claimLink, maybePartnerDetails.map(_._1)).toString())
    Done
  }
} 
Example 16
Source File: OnlyHttpsFilter.scala    From get-you-a-license   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package filters

import akka.stream.Materializer
import play.api.{Environment, Mode}
import play.api.http.HeaderNames
import play.api.mvc.{Filter, RequestHeader, Result, Results}

import scala.concurrent.{ExecutionContext, Future}

class OnlyHttpsFilter(environment: Environment)(implicit val mat: Materializer, ec: ExecutionContext) extends Filter {
  def apply(nextFilter: (RequestHeader) => Future[Result])(requestHeader: RequestHeader): Future[Result] = {
    nextFilter(requestHeader).map { result =>
      if (requestHeader.secure || environment.mode == Mode.Dev) {
        result
      }
      else {
        Results.MovedPermanently("https://" + requestHeader.host + requestHeader.uri)
      }
    }
  }
} 
Example 17
Source File: BroccoliSimpleAuthorization.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package jp.t2v.lab.play2.auth

import de.frosner.broccoli.auth.{Account, AuthMode}
import de.frosner.broccoli.conf
import de.frosner.broccoli.controllers.AuthConfigImpl
import de.frosner.broccoli.services.SecurityService
import jp.t2v.lab.play2.stackc.{RequestAttributeKey, RequestWithAttributes, StackableController}
import play.api.mvc.{Controller, RequestHeader, Result}

import scala.concurrent.Future

trait BroccoliSimpleAuthorization extends StackableController with AsyncAuth with AuthConfigImpl {

  self: Controller with AuthConfig =>

  val securityService: SecurityService

  private[auth] case object AuthKey extends RequestAttributeKey[User]

  override def proceed[A](req: RequestWithAttributes[A])(
      f: RequestWithAttributes[A] => Future[Result]): Future[Result] = {
    implicit val (r, ctx) = (req, StackActionExecutionContext(req))
    securityService.authMode match {
      case AuthMode.Conf => {
        restoreUser recover {
          case _ => None -> identity[Result] _
        } flatMap {
          case (Some(u), cookieUpdater) => super.proceed(req.set(AuthKey, u))(f).map(cookieUpdater)
          case (None, _)                => authenticationFailed(req)
        }
      }
      case AuthMode.None => {
        super.proceed(req)(f)
      }
    }
  }

  implicit def loggedIn(implicit req: RequestWithAttributes[_]): User = securityService.authMode match {
    case AuthMode.Conf => req.get(AuthKey).get
    case AuthMode.None => Account.anonymous
  }

  def getSessionId(request: RequestHeader): Option[AuthenticityToken] = extractToken(request)

} 
Example 18
Source File: AuthConfigImpl.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.controllers

import com.mohiva.play.silhouette.api.LoginInfo
import com.mohiva.play.silhouette.impl.providers.CredentialsProvider
import de.frosner.broccoli.auth.{Account, Role}
import de.frosner.broccoli.services.SecurityService
import jp.t2v.lab.play2.auth._
import play.api.{Environment, Mode}
import play.api.cache.CacheApi
import play.api.libs.json.JsString
import play.api.mvc.{RequestHeader, Result, Results}

import scala.concurrent.{ExecutionContext, Future}
import scala.reflect.ClassTag

trait AuthConfigImpl extends AuthConfig {

  val securityService: SecurityService

  val playEnv: Environment

  val cacheApi: CacheApi

  type Id = String

  type User = Account

  type Authority = Role

  val idTag: ClassTag[Id] = scala.reflect.classTag[Id]

  val sessionTimeoutInSeconds = securityService.sessionTimeoutInSeconds

  val cookieSecure = securityService.cookieSecure

  override lazy val idContainer: AsyncIdContainer[Id] = securityService.allowMultiLogin match {
    case true  => AsyncIdContainer(new MultiLoginCacheIdContainer[Id](cacheApi))
    case false => AsyncIdContainer(new CacheIdContainer[Id])
  }

  def resolveUser(id: Id)(implicit ctx: ExecutionContext): Future[Option[User]] =
    securityService.identityService.retrieve(LoginInfo(CredentialsProvider.ID, id))

  def loginSucceeded(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] =
    Future.successful(Results.Ok(JsString("Login successful!"))) // the content is not used anyway as the controller replaces it

  def logoutSucceeded(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] =
    Future.successful(Results.Ok(JsString("Logout successful!")))

  def authenticationFailed(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] =
    Future.successful(Results.Forbidden("Authentication failed."))

  override def authorizationFailed(request: RequestHeader, user: User, authority: Option[Authority])(
      implicit context: ExecutionContext): Future[Result] =
    Future.successful(Results.Forbidden(
      s"Authorization failed: Your privileges (${user.role}) are not matching the required (${authority.getOrElse("None")})."))

  def authorize(user: User, authority: Authority)(implicit ctx: ExecutionContext): Future[Boolean] = Future.successful {
    user.role match {
      case Role.Administrator => true
      case Role.Operator      => authority == Role.Operator || authority == Role.User
      case Role.User          => authority == Role.User
    }
  }

  override lazy val tokenAccessor = new CookieTokenAccessor(
    cookieName = AuthConfigImpl.CookieName,
    cookieSecureOption = playEnv.mode == Mode.Prod && cookieSecure,
    cookieHttpOnlyOption = true,
    cookieDomainOption = None,
    cookiePathOption = "/",
    cookieMaxAge = Some(sessionTimeoutInSeconds)
  )

}

object AuthConfigImpl {

  val CookieName = "BROCCOLI_SESS_ID"

} 
Example 19
Source File: IndexRenderService.scala    From silhouette-vuejs-app   with Apache License 2.0 5 votes vote down vote up
package models.services

import javax.inject.Inject
import play.api.mvc.RequestHeader
import play.filters.csrf.CSRF
import play.filters.csrf.CSRF.Token

import scala.io.Source

class IndexRenderService @Inject() () {

  def render(title: Option[String] = None, meta: Seq[(String, String)] = Seq.empty)(implicit request: RequestHeader): String = {
    val metaTags = title.map(t => s"<title>$t</title>").getOrElse("") +
      meta.map { case (n, c) => s"""<meta name="$n" content="$c">""" }.mkString("")

    val html = Source.fromFile("public/ui/index.html").mkString
    setCsrfToken(html).replace("</head>", s"$metaTags</head>")
  }

  def setCsrfToken(html: String)(implicit request: RequestHeader): String = {
    val Token(_, value) = CSRF.getToken.get

    html.replace("csrf-token-value=\"\"", s"csrf-token-value='$value'")
  }
} 
Example 20
Source File: PreferencesActions.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.document.settings.actions

import controllers.document.settings.SettingsController
import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.mvc.RequestHeader
import services.HasNullableSeq
import services.document.ExtendedDocumentMetadata
import services.entity.EntityType
import services.user.User

case class GazetteerPreferences(useAll: Boolean, includes: Seq[String])

object GazetteerPreferences extends HasNullableSeq {
  
  implicit val gazetteerPreferencesFormat: Format[GazetteerPreferences] = (
    (JsPath \ "use_all").format[Boolean] and
    (JsPath \ "includes").formatNullable[Seq[String]]
      .inmap(fromOptSeq[String], toOptSeq[String])
  )(GazetteerPreferences.apply, unlift(GazetteerPreferences.unapply))
  
  val DEFAULTS = GazetteerPreferences(true, Seq.empty[String])

}

trait PreferencesActions { self: SettingsController =>
  
  def showAnnotationPreferences(doc: ExtendedDocumentMetadata, user: User)(implicit request: RequestHeader) = {
    val fGazetteers= self.authorities.listAll(Some(EntityType.PLACE))
    val fCurrentPrefs = self.documents.getDocumentPreferences(doc.id)
    
    val f = for {
      gazetteers <- fGazetteers
      currentPrefs <- fCurrentPrefs
    } yield (gazetteers, currentPrefs)
    
    f.map { case (gazetteers, allPrefs) =>
      val gazetteerPrefs = allPrefs
        .find(_.getPreferenceName == "authorities.gazetteers")
        .flatMap(str => Json.fromJson[GazetteerPreferences](Json.parse(str.getPreferenceValue)).asOpt)
        .getOrElse(GazetteerPreferences.DEFAULTS)
        
      Ok(views.html.document.settings.preferences(doc, user, gazetteers, gazetteerPrefs))
    }
  }
    
  def setGazetteerPreferences(docId: String) = self.silhouette.SecuredAction.async { implicit request =>
    // JSON is parsed to case class and instantly re-serialized as a security/sanitization measure!
    jsonDocumentAdminAction[GazetteerPreferences](docId, request.identity.username, { case (document, prefs) =>      
      self.documents.upsertPreferences(docId, "authorities.gazetteers", Json.stringify(Json.toJson(prefs))).map { success =>
        if (success) Ok
        else InternalServerError
      }
    })
  }
  
} 
Example 21
Source File: PlayServerTests.scala    From tapir   with Apache License 2.0 5 votes vote down vote up
package sttp.tapir.server.play

import akka.actor.ActorSystem
import cats.data.NonEmptyList
import cats.effect.{IO, Resource}
import play.api.Mode
import play.api.mvc.{Handler, RequestHeader}
import play.api.routing.Router
import play.api.routing.Router.Routes
import play.core.server.{DefaultAkkaHttpServerComponents, ServerConfig}
import sttp.tapir.Endpoint
import sttp.tapir.server.tests.ServerTests
import sttp.tapir.server.{DecodeFailureHandler, ServerDefaults, ServerEndpoint}
import sttp.tapir.tests.{Port, PortCounter}

import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Await, Future}
import scala.reflect.ClassTag

class PlayServerTests extends ServerTests[Future, Nothing, Router.Routes] {
  override def multipleValueHeaderSupport: Boolean = false
  override def multipartInlineHeaderSupport: Boolean = false
  override def streamingSupport: Boolean = false

  private implicit val actorSystem: ActorSystem = ActorSystem()

  override protected def afterAll(): Unit = {
    Await.result(actorSystem.terminate(), 5.seconds)
    super.afterAll()
  }

  override def pureResult[T](t: T): Future[T] = Future.successful(t)

  override def suspendResult[T](t: => T): Future[T] = Future(t)

  override def route[I, E, O](
      e: ServerEndpoint[I, E, O, Nothing, Future],
      decodeFailureHandler: Option[DecodeFailureHandler]
  ): Routes = {
    implicit val serverOptions: PlayServerOptions =
      PlayServerOptions.default.copy(decodeFailureHandler = decodeFailureHandler.getOrElse(ServerDefaults.decodeFailureHandler))
    e.toRoute
  }

  override def routeRecoverErrors[I, E <: Throwable, O](e: Endpoint[I, E, O, Nothing], fn: I => Future[O])(implicit
      eClassTag: ClassTag[E]
  ): Routes = {
    e.toRouteRecoverErrors(fn)
  }

  override def server(routes: NonEmptyList[Routes], port: Port): Resource[IO, Unit] = {
    val components = new DefaultAkkaHttpServerComponents {
      override lazy val serverConfig: ServerConfig = ServerConfig(port = Some(port), address = "127.0.0.1", mode = Mode.Test)
      override def router: Router =
        Router.from(
          routes.reduce((a: Routes, b: Routes) => {
            val handler: PartialFunction[RequestHeader, Handler] = {
              case request => a.applyOrElse(request, b)
            }

            handler
          })
        )
    }
    val bind = IO {
      components.server
    }
    Resource.make(bind)(s => IO(s.stop())).map(_ => ())
  }

  override val portCounter: PortCounter = new PortCounter(38000)
} 
Example 22
Source File: PlayDecodeInputContext.scala    From tapir   with Apache License 2.0 5 votes vote down vote up
package sttp.tapir.server.play

import akka.stream.Materializer
import play.api.mvc.RequestHeader
import sttp.model.{Method, QueryParams}
import sttp.tapir.server.internal.DecodeInputsContext
import sttp.tapir.model.ServerRequest

private[play] class PlayDecodeInputContext(request: RequestHeader, pathConsumed: Int = 0, serverOptions: PlayServerOptions)(implicit
    mat: Materializer
) extends DecodeInputsContext {
  override def method: Method = Method(request.method.toUpperCase())

  override def nextPathSegment: (Option[String], DecodeInputsContext) = {
    val path = request.path.drop(pathConsumed)
    val nextStart = path.dropWhile(_ == '/')
    val segment = nextStart.split("/", 2) match {
      case Array("")   => None
      case Array(s)    => Some(s)
      case Array(s, _) => Some(s)
    }
    val charactersConsumed = segment.map(_.length).getOrElse(0) + (path.length - nextStart.length)

    (segment, new PlayDecodeInputContext(request, pathConsumed + charactersConsumed, serverOptions))
  }
  override def header(name: String): List[String] = request.headers.toMap.get(name).toList.flatten
  override def headers: Seq[(String, String)] = request.headers.headers
  override def queryParameter(name: String): Seq[String] = request.queryString.get(name).toSeq.flatten
  override def queryParameters: QueryParams = QueryParams.fromMultiMap(request.queryString)
  override def bodyStream: Any = throw new UnsupportedOperationException("Play doesn't support request body streaming")

  override def serverRequest: ServerRequest = new PlayServerRequest(request)
} 
Example 23
Source File: HttpsFilter.scala    From scala-clippy   with Apache License 2.0 5 votes vote down vote up
package controllers

import play.api.http.Status
import play.api.mvc.{Filter, RequestHeader, Result, Results}

import scala.concurrent.Future

class HttpsFilter extends Filter {
  def apply(nextFilter: (RequestHeader) => Future[Result])(requestHeader: RequestHeader): Future[Result] =
    requestHeader.headers.get("x-forwarded-proto") match {
      case Some(header) =>
        if (header == "https") {
          nextFilter(requestHeader)
        } else {
          Future.successful(
            Results.Redirect("https://" + requestHeader.host + requestHeader.uri, Status.MOVED_PERMANENTLY)
          )
        }
      case None => nextFilter(requestHeader)
    }
} 
Example 24
Source File: Filters.scala    From theGardener   with Apache License 2.0 5 votes vote down vote up
package filters

import akka.stream.Materializer
import javax.inject.Inject
import play.api.http.HttpFilters
import play.api.mvc.{EssentialFilter, RequestHeader, Result}
import play.api.{Environment, Mode}
import play.filters.cors.CORSFilter
import play.filters.gzip.GzipFilter

class Filters @Inject()(environment: Environment, corsFilter: CORSFilter)(implicit mat: Materializer) extends HttpFilters {

  
  private def shouldGzip = (requestHeader: RequestHeader, response: Result) => {
    val responseIsJavascript = response.body.contentType.exists(_.startsWith("application/javascript"))
    val requestPathShouldBeGzipped = requestHeader.path.contains("/api/")
    responseIsJavascript || requestPathShouldBeGzipped
  }

  private val gzipFilter = new GzipFilter(shouldGzip = shouldGzip)

  override val filters: Seq[EssentialFilter] = environment.mode match {
    case Mode.Dev =>
      // CORSFilter only for DEV mode: allow Angular app to call API on different port
      Seq(gzipFilter, corsFilter)
    case _ =>
      Seq(gzipFilter)
  }

} 
Example 25
Source File: writableHelperTest.scala    From api-first-hand   with MIT License 5 votes vote down vote up
package de.zalando.play.controllers

import akka.util.ByteString
import de.zalando.play.controllers.ResponseWriters.choose
import org.specs2.mutable.Specification
import play.api.http.Writeable
import play.api.mvc.RequestHeader

import scala.concurrent.ExecutionContext.Implicits


    override val custom: Seq[(String, ParserWrapper[_])] = Seq(
      "text/plain" -> any
    )
  }

  "WrappedBodyParsers" should {
    "find something" in {
      WrappedBodyParsers.anyParser[Any] must_== Nil
    }
    "not find anything for wrong type" in {
      binaryString.anyParser[String] must_== Nil
    }
    "find something for correct type" in {
      binaryString.anyParser[BinaryString].size must_== 1
    }
    "find something for every type if target is 'Any'" in {
      catchAll.anyParser[String].size must_== 1
      catchAll.anyParser[BinaryString].size must_== 1
    }
  }
}

object TestEnvironment {
  import Implicits.global
  val transformSeq: Seq[Any] => ByteString = a => ByteString.fromString(a.toString)
  val transformStr: String => ByteString = ByteString.fromString

  val seqText: WriteableWrapper[Seq[Any]] = Writeable(transformSeq, Some("text/plain"))

  val stringText: WriteableWrapper[String] = Writeable(transformStr, Some("text/plain"))

  val reg = Seq(seqText, stringText)
} 
Example 26
Source File: writeableHelper.scala    From api-first-hand   with MIT License 5 votes vote down vote up
package de.zalando.play.controllers

import akka.util.ByteString
import play.api.http.Writeable
import play.api.libs.json._
import play.api.mvc.Results.{ Redirect, Status }
import play.api.mvc.{ AnyContentAsMultipartFormData, RequestHeader, Results }

import scala.language.implicitConversions

case class WriteableWrapper[T](w: Writeable[T], m: Manifest[T])

object WriteableWrapper {
  implicit def writeable2wrapper[T](w: Writeable[T])(implicit m: Manifest[T]): WriteableWrapper[T] =
    WriteableWrapper(w, m)
  implicit val anyContentAsMultipartFormWritable: Writeable[AnyContentAsMultipartFormData] = {
    MultipartFormDataWritable.singleton.map(_.mdf)
  }
}


object ResponseWriters extends ResponseWritersBase

trait ResponseWritersBase {

  type ContentType = String

  def custom: Seq[WriteableWrapper[_]] = Seq.empty

  case class choose[T](mimeType: ContentType) {
    def apply[R <: Any](registry: Seq[WriteableWrapper[_]] = custom)(implicit m: Manifest[R]): Option[Writeable[R]] =
      registry filter {
        _.w.contentType.exists(_ == mimeType)
      } find { p =>
        m.runtimeClass.isAssignableFrom(p.m.runtimeClass)
      } map {
        _.asInstanceOf[WriteableWrapper[R]]
      } map (_.w)
  }

  implicit val jsonTranslatedParsingErrorWrites = Json.writes[TranslatedParsingError]

  implicit val jsonTranslatedParsingErrorsContainerWrites = Json.writes[TranslatedParsingErrorsContainer]
}

object WrappedBodyParsers extends WrappedBodyParsersBase

trait WrappedBodyParsersBase {
  implicit def parser2parserWrapper[T](p: Parser[T])(implicit m: Manifest[T]): ParserWrapper[T] = ParserWrapper(p, m)
  type Parser[T] = ByteString => T
  case class ParserWrapper[T](p: Parser[T], m: Manifest[T])
  val custom: Seq[(String, ParserWrapper[_])] = Seq.empty
  def anyParser[T](implicit manifest: Manifest[T]): Seq[(String, Parser[T])] =
    custom.filter(_._2.m.runtimeClass.isAssignableFrom(manifest.runtimeClass)).map { e =>
      e.copy(_2 = e._2.asInstanceOf[ParserWrapper[T]].p)
    }
  def optionParser[T](implicit manifest: Manifest[T]): Seq[(String, Parser[Option[T]])] = anyParser[Option[T]]
}

trait ResultWrapper[ResultT] {
  val emptyByteString = akka.util.CompactByteString.empty
  def statusCode: Int
  def result: ResultT
  def toResultWithWriter(implicit writer: Writeable[ResultT]): play.api.mvc.Result =
    if (statusCode / 100 == 3)
      Redirect(result.toString, statusCode)
    else
      Status(statusCode)(result)

  def writer: String => Option[Writeable[ResultT]]
  def toResult(mimeType: String): Option[play.api.mvc.Result] =
    if (statusCode / 100 == 3)
      Option(Redirect(result.toString, statusCode))
    else
      writer(mimeType).map(Status(statusCode)(result)(_))

} 
Example 27
Source File: WSPlayListener.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
package loci
package communicator
package ws.akka

import java.net.URI
import java.util.concurrent.ConcurrentLinkedQueue

import play.api.mvc.Security.AuthenticatedRequest
import play.api.mvc.{RequestHeader, Results, WebSocket}

import scala.concurrent.Future
import scala.util.{Failure, Success, Try}

private object WSPlayListener {
  locally(WSPlayListener)

  def apply[P <: WS: WSProtocolFactory](properties: WS.Properties) =
    new Listener[P] with WebSocketHandler {
      private def webSocket(authenticated: Either[Option[String], Any]) =
        WebSocket { request =>
          val uri = new URI(s"dummy://${request.host}")
          val host = uri.getHost
          val port = uri.getPort

          val certificates = request.clientCertificateChain.toSeq.flatten
          val isAuthenticated =
            authenticated.isRight ||
            compatibility.either.left(authenticated).nonEmpty ||
            (request.secure && certificates.nonEmpty)
          val isProtected = request.secure
          val isEncrypted = request.secure

          val ws = implicitly[WSProtocolFactory[P]] make (
            request.uri,
            Option(host),
            if (port < 0) None else Some(port),
            this, isAuthenticated, isEncrypted, isProtected,
            Some(Left(request)),
            authenticated.left.toOption.flatten toRight certificates)

          Future successful (ws match {
            case Failure(exception) =>
              connectionEstablished(Failure(exception))
              Left(Results.NotFound)

            case Success(ws) =>
              Right(WSPlayHandler handleWebSocket (
                Future successful ws, properties, connectionEstablished))
          })
        }

      def apply(authenticatedName: String) = webSocket(Left(Some(authenticatedName)))
      def apply(authenticatedName: Option[String]) = webSocket(Left(authenticatedName))
      def apply(request: RequestHeader) = request match {
        case request: AuthenticatedRequest[_, _] =>
          request.user match {
            case user: String =>
              webSocket(Left(Some(user)))(request)
            case user =>
              webSocket(Right(user))(request)
          }
        case _ =>
          webSocket(Left(None))(request)
      }

      private val connected = new ConcurrentLinkedQueue[Connected[P]]

      private def connectionEstablished(connection: Try[Connection[P]]) = {
        val iterator = connected.iterator
        while (iterator.hasNext)
          iterator.next().fire(connection)
      }

      protected def startListening(connectionEstablished: Connected[P]): Try[Listening] = {
        connected.add(connectionEstablished)

        Success(new Listening {
          def stopListening(): Unit = connected.remove(connectionEstablished)
        })
      }
    }
} 
Example 28
Source File: PlayUtils.scala    From scalingua   with Apache License 2.0 5 votes vote down vote up
package ru.makkarpov.scalingua.play

import play.api.mvc.RequestHeader
import play.twirl.api.Html
import ru.makkarpov.scalingua._

import scala.language.experimental.macros

object PlayUtils {
  class StringInterpolator(val sc: StringContext) extends AnyVal {
    def h(args: Any*)(implicit lang: Language, outputFormat: OutputFormat[Html]): Html =
      macro Macros.interpolate[Html]

    def lh(args: Any*)(implicit outputFormat: OutputFormat[Html]): LValue[Html] =
      macro Macros.lazyInterpolate[Html]

    def ph(args: Any*)(implicit lang: Language, outputFormat: OutputFormat[Html]): Html =
      macro Macros.pluralInterpolate[Html]

    def lph(args: Any*)(outputFormat: OutputFormat[Html]): LValue[Html] =
      macro Macros.lazyPluralInterpolate[Html]
  }

  // Modified to match only correct doubles
  private val qPattern = ";\\s*q=((?:[0-9]+\\.)?[0-9]+)".r

  def languageFromAccept(accept: String)(implicit msg: Messages): Language = {
    val langs = (for {
      value0 <- accept.split(',')
      value = value0.trim
    } yield {
      qPattern.findFirstMatchIn(value) match {
        case Some(m) => (BigDecimal(m.group(1)), m.before.toString)
        case None => (BigDecimal(1.0), value) // “The default value is q=1.”
      }
    }).sortBy(-_._1).iterator

    while (langs.hasNext) {
      val (_, id) = langs.next()
      val lng = LanguageId.get(id)

      if (lng.isDefined && msg.contains(lng.get))
        return msg(lng.get)
    }

    Language.English
  }
} 
Example 29
Source File: I18n.scala    From scalingua   with Apache License 2.0 5 votes vote down vote up
package ru.makkarpov.scalingua.play

import play.api.http.HeaderNames
import play.api.mvc.RequestHeader
import play.twirl.api.Html
import ru.makkarpov.scalingua
import ru.makkarpov.scalingua._

import scala.language.experimental.macros
import scala.language.implicitConversions

trait I18n extends scalingua.I18n {
  type LHtml = LValue[Html]

  implicit val htmlOutputFormat = new OutputFormat[Html] {
    override def convert(s: String): Html = Html(s)

    override def escape(s: String): String = {
      val ret = new StringBuilder
      var i = 0
      ret.sizeHint(s.length)
      while (i < s.length) {
        s.charAt(i) match {
          case '<' => ret.append("&lt;")
          case '>' => ret.append("&gt;")
          case '"' => ret.append("&quot;")
          case '\'' => ret.append("&#x27;")
          case '&' => ret.append("&amp;")
          case c => ret += c
        }
        i += 1
      }
      ret.result()
    }
  }

  // The conversion from `RequestHeader` to `LanguageId` will imply information loss:
  // Suppose browser sent the following language precedence list `xx_YY`, `zz_WW`, `en_US`.
  // This conversion will have no information about available languages, so it will result in
  // `LanguageId("xx", "YY")` even if this language is absent. By supplying implicit `Messages`
  // too, we will have enough information to skip unsupported languages and return supported
  // one with respect to priority.

  implicit def requestHeader2Language(implicit rq: RequestHeader, msg: Messages): Language =
    rq.headers.get(HeaderNames.ACCEPT_LANGUAGE).map(PlayUtils.languageFromAccept).getOrElse(Language.English)

  implicit def stringContext2Interpolator1(sc: StringContext): PlayUtils.StringInterpolator =
    new PlayUtils.StringInterpolator(sc)

  def th(msg: String, args: (String, Any)*)(implicit lang: Language, outputFormat: OutputFormat[Html]): Html =
    macro Macros.singular[Html]

  def lth(msg: String, args: (String, Any)*)(implicit outputFormat: OutputFormat[Html]): LHtml =
    macro Macros.lazySingular[Html]

  def tch(ctx: String, msg: String, args: (String, Any)*)(implicit lang: Language, outputFormat: OutputFormat[Html]): Html =
    macro Macros.singularCtx[Html]

  def ltch(ctx: String, msg: String, args: (String, Any)*)(implicit outputFormat: OutputFormat[Html]): LHtml =
    macro Macros.lazySingularCtx[Html]

  def p(msg: String, msgPlural: String, n: Long, args: (String, Any)*)
       (implicit lang: Language, outputFormat: OutputFormat[Html]): Html =
    macro Macros.plural[Html]

  def lp(msg: String, msgPlural: String, n: Long, args: (String, Any)*)
        (implicit outputFormat: OutputFormat[Html]): LHtml =
    macro Macros.lazyPlural[Html]

  def pc(ctx: String, msg: String, msgPlural: String, n: Long, args: (String, Any)*)
        (implicit lang: Language, outputFormat: OutputFormat[Html]): Html =
    macro Macros.pluralCtx[Html]

  def lpc(ctx: String, msg: String, msgPlural: String, n: Long, args: (String, Any)*)
         (implicit outputFormat: OutputFormat[Html]): LHtml =
    macro Macros.lazyPluralCtx[Html]
}

object I18n extends I18n 
Example 30
Source File: CSRFSpec.scala    From play-ui   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.play.views.helpers

import org.scalatest.WordSpec
import org.scalatestplus.play.OneAppPerTest
import play.api.Application
import play.api.mvc.RequestHeader
import play.api.test.FakeRequest
import play.filters.csrf.CSRF.Token
import play.filters.csrf.{CSRFConfigProvider, CSRFFilter}

trait CSRFSpec extends WordSpec with OneAppPerTest {
  implicit class RichFakeRequest[T](fakeRequest: FakeRequest[T])(implicit app: Application) {
    def withCSRFToken: RequestHeader = {
      val csrfConfig = app.injector.instanceOf[CSRFConfigProvider].get
      val csrfFilter = app.injector.instanceOf[CSRFFilter]
      val token      = csrfFilter.tokenProvider.generateToken

      fakeRequest
        .copyFakeRequest(
          tags =
            fakeRequest.tags ++
              Map(
                Token.NameRequestTag -> csrfConfig.tokenName,
                Token.RequestTag     -> token
              ))
    }
  }

  implicit lazy val request = FakeRequest().withCSRFToken
} 
Example 31
Source File: WorkspaceController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.my

import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseController, Security, HasPrettyPrintJSON}
import javax.inject.{Inject, Singleton}
import services.contribution.{Contribution, ContributionService}
import services.user.{User, UserService}
import org.webjars.play.WebJarsUtil
import play.api.{Configuration, Environment}
import play.api.i18n.I18nSupport
import play.api.libs.json.Json
import play.api.mvc.{ControllerComponents, RequestHeader}
import services.document.DocumentService
import scala.concurrent.{ExecutionContext, Future}

@Singleton
class WorkspaceController @Inject() (
  val components: ControllerComponents,
  val contributions: ContributionService,
  val users: UserService,
  val config: Configuration,
  val silhouette: Silhouette[Security.Env],
  implicit val documents: DocumentService,
  implicit val ctx: ExecutionContext,
  implicit val env: Environment,
  implicit val webjars: WebJarsUtil
) extends BaseController(components, config, users) with I18nSupport with HasPrettyPrintJSON {

  
  def workspace(usernameInPath: String) = silhouette.UserAwareAction.async { implicit request =>    
    // If the user is logged in & the name in the path == username it's the profile owner
    val isProfileOwner = request.identity match {
      case Some(userWithRoles) => userWithRoles.username.equalsIgnoreCase(usernameInPath)
      case None => false
    }
    
    if (isProfileOwner)
      Future.successful(Ok(views.html.my.workspace()))
    else
      renderPublicProfile(usernameInPath, request.identity)
  }

  def activityFeed(usernameInPath: String) = silhouette.UserAwareAction.async { implicit request =>
    val loggedInAs = request.identity.map(_.username)
    contributions.getUserActivityFeed(Seq(usernameInPath), loggedInAs).map { response => 
      jsonOk(Json.toJson(response))
    } 
  }
  
} 
Example 32
Source File: HasVisitLogging.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers

import eu.bitwalker.useragentutils.UserAgent
import services.visit._
import services.ContentType
import services.RuntimeAccessLevel
import services.generated.tables.records.{DocumentRecord, DocumentFilepartRecord}
import org.joda.time.DateTime
import play.api.mvc.{AnyContent, RequestHeader}
import play.api.http.HeaderNames
import scala.concurrent.Future

trait HasVisitLogging {
    
  
  private def log(
      doc: Option[DocumentRecord],
      part: Option[DocumentFilepartRecord],
      responseFormat: String,
      accesslevel: Option[RuntimeAccessLevel]
    )(implicit request: RequestHeader, visitService: VisitService): Future[Unit] = {
    
    val userAgentHeader = request.headers.get(HeaderNames.USER_AGENT)
    val userAgent = userAgentHeader.map(ua => UserAgent.parseUserAgentString(ua))
    val os = userAgent.map(_.getOperatingSystem)
    
    val item = doc.map(doc => VisitedItem(
      doc.getId,
      doc.getOwner,
      part.map(_.getId),
      part.flatMap(pt => ContentType.withName(pt.getContentType))
    ))
    
    val visit = Visit(
      request.uri,
      request.headers.get(HeaderNames.REFERER),
      DateTime.now(),
      Client(
        userAgentHeader.getOrElse("UNKNOWN"),
        userAgent.map(_.getBrowser.getGroup.getName).getOrElse("UNKNOWN"),
        os.map(_.getName).getOrElse("UNKNOWN"),
        os.map(_.getDeviceType.getName).getOrElse("UNKNOWN")  
      ),
      responseFormat,
      item,
      accesslevel)
    
    if (HasVisitLogging.isBot(visit))
      Future.successful(())
    else
      visitService.insertVisit(visit)    
  }
  
  def logPageView()(implicit request: RequestHeader, visitService: VisitService) =
    log(None, None, "text/html", None)

  def logDocumentView(
      doc: DocumentRecord, part: Option[DocumentFilepartRecord], accesslevel: RuntimeAccessLevel
    )(implicit request: RequestHeader, visitService: VisitService) = 
      log(Some(doc), part, "text/html", Some(accesslevel))
    
  def logDownload(
      doc: DocumentRecord, responseFormat: String
    )(implicit request: RequestHeader, visitService: VisitService) =
      log(Some(doc), None, responseFormat, None)
     
    
}

object HasVisitLogging {
  
  // If one of these keywords appears in the UA header, treat as bot
  private val USER_AGENT_EXCLUDES = Set("uptimerobot")
   
  def isBot(visit: Visit) =
    USER_AGENT_EXCLUDES.find(visit.client.userAgent.contains(_)).isDefined
  
} 
Example 33
Source File: HelpController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.help

import controllers.HasVisitLogging
import javax.inject.{Inject, Singleton}
import services.visit.VisitService
import org.webjars.play.WebJarsUtil
import play.api.{Configuration, Environment}
import play.api.mvc.{Action, AbstractController, ControllerComponents, RequestHeader}
import play.twirl.api.HtmlFormat
import scala.concurrent.ExecutionContext
import scala.io.Source
import scala.util.Try
import services.entity.{AuthorityFileService, EntityType}

@Singleton
class HelpController @Inject() (
  val authorities: AuthorityFileService,
  val components: ControllerComponents,
  val config: Configuration,
  val env: Environment,
  implicit val ctx: ExecutionContext,
  implicit val visits: VisitService,
  implicit val webjars: WebJarsUtil
) extends AbstractController(components) with HasVisitLogging {

  private val adminEmail = config.get[String]("admin.email")
  private val imprint =
    Try(Source.fromFile(env.getFile("conf/imprint"))).toOption.map { _.getLines.mkString("\n") }

  private def result(template: HtmlFormat.Appendable)(implicit request: RequestHeader) = {
    logPageView()
    Ok(template)
  }

  def localizedTutorial(lang: String) = Action { implicit request =>
    lang.toUpperCase match {
      case "DE" => result(views.html.help.tutorial.tutorial_de())
      case "ES" => result(views.html.help.tutorial.tutorial_es())
      case "FA" => result(views.html.help.tutorial.tutorial_fa())
      case "FR" => result(views.html.help.tutorial.tutorial_fr())
      case "IT" => result(views.html.help.tutorial.tutorial_it())
      case "NL" => result(views.html.help.tutorial.tutorial_nl())
      case "TR" => result(views.html.help.tutorial.tutorial_tr())
      case _ => NotFound(views.html.error404())
    }
  }

  def faq = Action.async { implicit request => 
    authorities.listAll(Some(EntityType.PLACE)).map { gazetteers =>
      result(views.html.help.faq(gazetteers)) 
    }
  }

  def index = Action { implicit request => result(views.html.help.index()) }

  def about        = Action { implicit request => result(views.html.help.general.about(imprint, adminEmail)) }
  def privacy      = Action { implicit request => result(views.html.help.general.privacy(adminEmail)) }
  def relations    = Action { implicit request => result(views.html.help.relations()) }
  def cloning      = Action { implicit request => result(views.html.help.cloning()) }
  def sharingLinks = Action { implicit request => result(views.html.help.sharing_links()) }
  def terms        = Action { implicit request => result(views.html.help.general.terms()) }
  def tutorial     = Action { implicit request => result(views.html.help.tutorial.tutorial()) }
  def workspace    = Action { implicit request => result(views.html.help.workspace()) }

  def swaggerUi = Action {
    Redirect(url = "/webjars/swagger-ui/2.2.0/index.html", queryString = Map("url" -> Seq("/swagger.json")))
  }

} 
Example 34
Source File: ErrorHandler.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
import javax.inject.{ Inject, Provider }
import play.api.{ Configuration, Environment, Logger, OptionalSourceMapper, UsefulException }
import play.api.http.DefaultHttpErrorHandler
import play.api.mvc.RequestHeader
import play.api.mvc.Results._
import play.api.routing.Router
import scala.concurrent.Future

class ErrorHandler @Inject() (
    env: Environment,
    config: Configuration,
    sourceMapper: OptionalSourceMapper,
    router: Provider[Router]
  ) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  override def onProdServerError(request: RequestHeader, exception: UsefulException) =
    Future.successful(InternalServerError(s"An error occurred: ${exception.getMessage}"))

  override def onClientError(request: RequestHeader, statusCode: Int, message: String) = {
    if (statusCode == 413) // Request entity too large
      Future.successful(EntityTooLarge("Could not upload the file - too large"))
    else if (statusCode == 404) // Not Found
      Future.successful(NotFound(views.html.error404()))
    else
      super.onClientError(request, statusCode, message)
  }

} 
Example 35
Source File: ZipkinTraceFilter.scala    From play-zipkin-tracing   with Apache License 2.0 5 votes vote down vote up
package brave.play.filter

import javax.inject.Inject

import akka.stream.Materializer
import brave.play.ZipkinTraceServiceLike
import play.api.mvc.{Filter, Headers, RequestHeader, Result}
import play.api.routing.Router

import scala.concurrent.Future
import scala.util.Failure


class ZipkinTraceFilter @Inject() (tracer: ZipkinTraceServiceLike)(implicit val mat: Materializer) extends Filter {

  import tracer.executionContext
  private val reqHeaderToSpanName: RequestHeader => String = ZipkinTraceFilter.ParamAwareRequestNamer

  def apply(nextFilter: RequestHeader => Future[Result])(req: RequestHeader): Future[Result] = {
    val serverSpan = tracer.serverReceived(
      spanName = reqHeaderToSpanName(req),
      span = tracer.newSpan(req.headers)((headers, key) => headers.get(key))
    )
    val result = nextFilter(req.withHeaders(new Headers(
      (req.headers.toMap.mapValues(_.headOption getOrElse "") ++ tracer.toMap(serverSpan)).toSeq
    )))
    result.onComplete {
      case Failure(t) => tracer.serverSend(serverSpan, "failed" -> s"Finished with exception: ${t.getMessage}")
      case _ => tracer.serverSend(serverSpan)
    }
    result
  }
}

object ZipkinTraceFilter {
  val ParamAwareRequestNamer: RequestHeader => String = { reqHeader =>
    import org.apache.commons.lang3.StringUtils
    val pathPattern = StringUtils.replace(
      reqHeader.attrs.get(Router.Attrs.HandlerDef).map(_.path).getOrElse(reqHeader.path),
      "<[^/]+>", ""
    )
    s"${reqHeader.method} - $pathPattern"
  }
} 
Example 36
Source File: MetricsFilter.scala    From play-prometheus-filters   with MIT License 5 votes vote down vote up
package com.github.stijndehaes.playprometheusfilters.filters
import akka.stream.Materializer
import com.github.stijndehaes.playprometheusfilters.metrics.RequestMetric
import io.prometheus.client.Collector
import play.api.Configuration
import play.api.mvc.{Filter, RequestHeader, Result}

import scala.concurrent.{ExecutionContext, Future}


abstract class MetricsFilter(configuration: Configuration)(implicit val mat: Materializer, ec: ExecutionContext) extends Filter {

  val metrics: List[RequestMetric[_, RequestHeader, Result]]

  val excludePaths = {
    import collection.JavaConverters._
    Option(configuration.underlying)
      .map(_.getStringList("play-prometheus-filters.exclude.paths"))
      .map(_.asScala.toSet)
      .map(_.map(_.r))
      .getOrElse(Set.empty)
  }

  def apply(nextFilter: RequestHeader => Future[Result])
           (requestHeader: RequestHeader): Future[Result] = {

    // check if current uri is excluded from metrics
    def urlIsExcluded = excludePaths.exists(_.findFirstMatchIn(requestHeader.uri).isDefined)

    val startTime = System.nanoTime

    nextFilter(requestHeader).map { implicit result =>
      implicit val rh = requestHeader

      if (!urlIsExcluded) {
        val endTime = System.nanoTime
        val requestTime = (endTime - startTime) / Collector.NANOSECONDS_PER_SECOND

        metrics.foreach(_.mark(requestTime))
      }

      result
    }
  }
} 
Example 37
Source File: ErrorHandler.scala    From metronome   with Apache License 2.0 5 votes vote down vote up
package dcos.metronome
package api

import org.slf4j.LoggerFactory
import play.api.http.HttpErrorHandler
import play.api.http.Status._
import play.api.libs.json.Json
import play.api.mvc.{RequestHeader, Result, Results}
import play.twirl.api.HtmlFormat

import scala.concurrent.Future

class ErrorHandler extends HttpErrorHandler {

  private[this] val log = LoggerFactory.getLogger(getClass)

  override def onClientError(request: RequestHeader, statusCode: Int, message: String): Future[Result] = {
    log.debug(s"Client Error on path ${request.path}. Message: $message Status: $statusCode")
    val outputMessage = if (statusCode == NOT_FOUND) { ErrorHandler.noRouteHandlerMessage }
    else { message }
    val json = Json.obj("message" -> escape(outputMessage), "requestPath" -> escape(request.path))
    Future.successful(Results.Status(statusCode)(json))
  }

  override def onServerError(request: RequestHeader, exception: Throwable): Future[Result] = {

    
  private def escape(msg: String): String = HtmlFormat.escape(msg).body
}

object ErrorHandler {
  val noRouteHandlerMessage = "Unknown route."
} 
Example 38
Source File: GroupApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import akka.actor.ActorSystem
import asura.app.AppErrorMessages
import asura.app.api.auth.Reserved
import asura.common.model.ApiResError
import asura.common.util.StringUtils
import asura.core.es.actor.ActivitySaveActor
import asura.core.es.model.{Activity, Group}
import asura.core.es.service.GroupService
import asura.core.model.QueryGroup
import asura.play.api.BaseApi.OkApiRes
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents
import play.api.Configuration
import play.api.mvc.{RequestHeader, Result}

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class GroupApi @Inject()(
                          implicit val system: ActorSystem,
                          val exec: ExecutionContext,
                          val configuration: Configuration,
                          val controllerComponents: SecurityComponents,
                        ) extends BaseApi {

  val administrators = configuration.getOptional[Seq[String]]("asura.admin").getOrElse(Nil).toSet
  val activityActor = system.actorOf(ActivitySaveActor.props())

  def getById(id: String) = Action.async { implicit req =>
    GroupService.getById(id).toOkResultByEsOneDoc(id)
  }

  def delete(id: String) = Action.async { implicit req =>
    checkPrivilege { user =>
      activityActor ! Activity(id, StringUtils.EMPTY, user, Activity.TYPE_DELETE_GROUP, id)
      GroupService.deleteGroup(id).toOkResult
    }
  }

  def put() = Action(parse.byteString).async { implicit req =>
    val group = req.bodyAs(classOf[Group])
    val user = getProfileId()
    group.fillCommonFields(user)
    if (Reserved.isReservedGroup(group.id)) {
      Future.successful(OkApiRes(ApiResError(getI18nMessage(AppErrorMessages.error_CanNotUseReservedGroup))))
    } else {
      GroupService.index(group).map(res => {
        activityActor ! Activity(group.id, StringUtils.EMPTY, user, Activity.TYPE_NEW_GROUP, group.id)
        toActionResultFromAny(res)
      })
    }
  }

  def query() = Action(parse.byteString).async { implicit req =>
    val queryGroup = req.bodyAs(classOf[QueryGroup])
    GroupService.queryGroup(queryGroup).toOkResultByEsList(false)
  }

  def update() = Action(parse.byteString).async { implicit req =>
    val group = req.bodyAs(classOf[Group])
    GroupService.updateGroup(group).toOkResult
  }

  private def checkPrivilege(func: String => Future[Result])(implicit request: RequestHeader): Future[Result] = {
    val user = getProfileId()
    val isAllowed = if (administrators.nonEmpty) administrators.contains(user) else true
    if (isAllowed) {
      func(user)
    } else {
      Future.successful(OkApiRes(ApiResError(getI18nMessage(AppErrorMessages.error_NotAllowedContactAdministrator, administrators.mkString(",")))))
    }
  }
} 
Example 39
Source File: AuthValidator.scala    From maha   with Apache License 2.0 5 votes vote down vote up
package com.yahoo.maha.core.auth

import play.api.Configuration
import play.api.mvc.{RequestHeader, Result, Results}

import scala.collection.immutable.Map

case class ValidationResult(success: Boolean, user: Option[String])

trait AuthValidator {
  def init(configuration: Configuration)
  def validate(requestHeader: RequestHeader) : ValidationResult
  def handleAuthCallback(requestHeader: RequestHeader) : Result
  def handleAuthFailure(requestHeader: RequestHeader) : Result
}

class DefaultAuthValidator extends AuthValidator {
  override def init(configuration: Configuration): Unit = {
  }

  override def validate(requestHeader: RequestHeader): ValidationResult = {
    ValidationResult(success = true, user = None)
  }

  override def handleAuthCallback(requestHeader: RequestHeader): Result = {
    Results.Ok
  }

  override def handleAuthFailure(requestHeader: RequestHeader): Result = {
    Results.Ok
  }
}

trait DruidAuthHeaderProvider {
  def init(configuration: Configuration)
  def getAuthHeaders : Map[String, String]
}

class DefaultDruidAuthHeaderProvider extends DruidAuthHeaderProvider {
  override def init(configuration: Configuration): Unit = {
  }

  override def getAuthHeaders: Map[String, String] = {
    Map.empty
  }
} 
Example 40
Source File: Authenticator.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package org.coursera.naptime.access.authenticator

import com.typesafe.scalalogging.StrictLogging
import org.coursera.common.concurrent.Futures
import org.coursera.naptime.NaptimeActionException
import org.coursera.naptime.access.authenticator.combiner.And
import org.coursera.naptime.access.authenticator.combiner.AnyOf
import org.coursera.naptime.access.authenticator.combiner.FirstOf
import play.api.http.Status.FORBIDDEN
import play.api.http.Status.UNAUTHORIZED
import play.api.mvc.RequestHeader

import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.util.control.NonFatal


  def maybeAuthenticate(requestHeader: RequestHeader)(
      implicit ec: ExecutionContext): Future[Option[Either[NaptimeActionException, A]]]

  def collect[B](f: PartialFunction[A, B]): Authenticator[B] = {
    val self = this
    new Authenticator[B] {
      override def maybeAuthenticate(requestHeader: RequestHeader)(
          implicit ec: ExecutionContext): Future[Option[Either[NaptimeActionException, B]]] = {

        Futures
          .safelyCall(self.maybeAuthenticate(requestHeader))
          .map(_.map(_.right.map(f.lift)))
          .map {
            case Some(Right(None))    => None
            case Some(Right(Some(b))) => Some(Right(b))
            case Some(Left(error))    => Some(Left(error))
            case None                 => None
          }
          .recover(Authenticator.errorRecovery)
      }
    }
  }

  def map[B](f: A => B): Authenticator[B] = collect(PartialFunction(f))

}

object Authenticator extends StrictLogging with AnyOf with FirstOf with And {

  def apply[P, A](
      parser: HeaderAuthenticationParser[P],
      decorator: Decorator[P, A]): Authenticator[A] = {

    new Authenticator[A] {
      def maybeAuthenticate(requestHeader: RequestHeader)(
          implicit ec: ExecutionContext): Future[Option[Either[NaptimeActionException, A]]] = {

        parser.parseHeader(requestHeader) match {
          case ParseResult.Success(parsed) =>
            Futures
              .safelyCall(decorator(parsed))
              .map { either =>
                either.left
                  .map { message =>
                    Some(Left(NaptimeActionException(FORBIDDEN, None, Some(message))))
                  }
                  .right
                  .map { decorated =>
                    Some(Right(decorated))
                  }
                  .merge
              }
              .recover(errorRecovery)
          case ParseResult.Error(message, status) =>
            Future.successful(
              Some(Left(NaptimeActionException(status, Some("auth.parse"), Some(message)))))
          case ParseResult.Skip => Future.successful(None)
        }
      }
    }

  }

  private[access] def authenticateAndRecover[A](
      authenticator: Authenticator[A],
      requestHeader: RequestHeader)(
      implicit ec: ExecutionContext): Future[Option[Either[NaptimeActionException, A]]] = {
    Futures
      .safelyCall(authenticator.maybeAuthenticate(requestHeader))
      .recover(errorRecovery)
  }

  def errorRecovery[A]: PartialFunction[Throwable, Option[Either[NaptimeActionException, A]]] = {
    case NonFatal(e) =>
      logger.error("Unexpected authentication error", e)
      val message = s"Unexpected authentication error: ${e.getMessage}"
      Some(Left(NaptimeActionException(UNAUTHORIZED, Some("auth.perms"), Some(message))))
  }

} 
Example 41
Source File: StructuredAccessControl.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package org.coursera.naptime.access

import org.coursera.naptime.NaptimeActionException
import org.coursera.naptime.access.authenticator.Authenticator
import org.coursera.naptime.access.authorizer.AuthorizeResult
import org.coursera.naptime.access.authorizer.Authorizer
import play.api.http.Status
import play.api.mvc.RequestHeader

import scala.concurrent.ExecutionContext
import scala.concurrent.Future


case class StructuredAccessControl[A](authenticator: Authenticator[A], authorizer: Authorizer[A])
    extends HeaderAccessControl[A] {

  override def run(requestHeader: RequestHeader)(
      implicit executionContext: ExecutionContext): Future[Either[NaptimeActionException, A]] = {

    Authenticator.authenticateAndRecover(authenticator, requestHeader).map { decoratedOption =>
      decoratedOption
        .map { either =>
          either.right.flatMap { decorated =>
            Authorizer.toResponse(authorizer.authorize(decorated), decorated)
          }
        }
        .getOrElse {
          StructuredAccessControl.missingResponse
        }
    }
  }

  override private[naptime] def check(authInfo: A): Either[NaptimeActionException, A] = {
    Authorizer.toResponse(authorizer.authorize(authInfo), authInfo)
  }
}

object StructuredAccessControl {

  private[access] val missingResponse = {
    Left(
      NaptimeActionException(
        Status.UNAUTHORIZED,
        Some("auth.perms"),
        Some("Missing authentication")))
  }

} 
Example 42
Source File: AuthMacroTest.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package org.coursera.naptime

import akka.stream.Materializer
import org.coursera.naptime.access.HeaderAccessControl
import org.coursera.naptime.model.KeyFormat
import org.coursera.naptime.resources.TopLevelCollectionResource
import org.coursera.naptime.router2._
import org.junit.Test
import org.scalatest.junit.AssertionsForJUnit
import org.scalatest.mockito.MockitoSugar
import play.api.libs.json.OFormat
import play.api.mvc.RequestHeader

import scala.concurrent.ExecutionContext

case class CustomAuth()

object CustomAuthorizer extends HeaderAccessControl[CustomAuth] {
  override def run(requestHeader: RequestHeader)(implicit executionContext: ExecutionContext) = ???
  override private[naptime] def check(authInfo: CustomAuth) = ???
}

class AuthorizedResource(
    implicit val executionContext: ExecutionContext,
    val materializer: Materializer)
    extends TopLevelCollectionResource[String, Item] {

  override def keyFormat: KeyFormat[String] = KeyFormat.stringKeyFormat

  override implicit def resourceFormat: OFormat[Item] = Item.jsonFormat

  override def resourceName: String = "items"

  implicit val fields = Fields.withDefaultFields("name")

  def get(id: String) =
    Nap
      .auth(CustomAuthorizer)
      .get { ctx =>
        ???
      }

}

object AuthorizedResource {
  val routerBuilder = Router.build[AuthorizedResource]
}

class AuthMacroTest extends AssertionsForJUnit with MockitoSugar with ResourceTestImplicits {

  val schema = AuthorizedResource.routerBuilder.schema

  @Test
  def get(): Unit = {
    val handler = schema.handlers.find(_.name === "get").get
    assert(handler.authType === Some("org.coursera.naptime.CustomAuth"))
  }

} 
Example 43
Source File: KeyAuthSrv.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.services

import java.util.Base64
import javax.inject.{Inject, Singleton}

import scala.concurrent.{ExecutionContext, Future}
import scala.util.Random

import play.api.libs.json.JsArray
import play.api.mvc.RequestHeader

import akka.stream.Materializer
import akka.stream.scaladsl.Sink

import org.elastic4play.controllers.Fields
import org.elastic4play.services.{AuthCapability, AuthContext, AuthSrv}
import org.elastic4play.{AuthenticationError, BadRequestError}

@Singleton
class KeyAuthSrv @Inject()(userSrv: UserSrv, implicit val ec: ExecutionContext, implicit val mat: Materializer) extends AuthSrv {
  override val name = "key"

  final protected def generateKey(): String = {
    val bytes = Array.ofDim[Byte](24)
    Random.nextBytes(bytes)
    Base64.getEncoder.encodeToString(bytes)
  }

  override val capabilities = Set(AuthCapability.authByKey)

  override def authenticate(key: String)(implicit request: RequestHeader): Future[AuthContext] = {
    import org.elastic4play.services.QueryDSL._
    // key attribute is sensitive so it is not possible to search on that field
    userSrv
      .find("status" ~= "Ok", Some("all"), Nil)
      ._1
      .filter(_.key().contains(key))
      .runWith(Sink.headOption)
      .flatMap {
        case Some(user) ⇒ userSrv.getFromUser(request, user, name)
        case None       ⇒ Future.failed(AuthenticationError("Authentication failure"))
      }
  }

  override def renewKey(username: String)(implicit authContext: AuthContext): Future[String] = {
    val newKey = generateKey()
    userSrv.update(username, Fields.empty.set("key", newKey)).map(_ ⇒ newKey)
  }

  override def getKey(username: String)(implicit authContext: AuthContext): Future[String] =
    userSrv.get(username).map(_.key().getOrElse(throw BadRequestError(s"User $username hasn't key")))

  override def removeKey(username: String)(implicit authContext: AuthContext): Future[Unit] =
    userSrv.update(username, Fields.empty.set("key", JsArray())).map(_ ⇒ ())
} 
Example 44
Source File: LocalAuthSrv.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.services

import javax.inject.{Inject, Singleton}

import scala.concurrent.{ExecutionContext, Future}
import scala.util.Random

import play.api.mvc.RequestHeader

import akka.stream.Materializer
import org.thp.cortex.models.User

import org.elastic4play.controllers.Fields
import org.elastic4play.services.{AuthCapability, AuthContext, AuthSrv}
import org.elastic4play.utils.Hasher
import org.elastic4play.{AuthenticationError, AuthorizationError}

@Singleton
class LocalAuthSrv @Inject()(userSrv: UserSrv, implicit val ec: ExecutionContext, implicit val mat: Materializer) extends AuthSrv {

  val name                  = "local"
  override val capabilities = Set(AuthCapability.changePassword, AuthCapability.setPassword)

  private[services] def doAuthenticate(user: User, password: String): Boolean =
    user.password().map(_.split(",", 2)).fold(false) {
      case Array(seed, pwd) ⇒
        val hash = Hasher("SHA-256").fromString(seed + password).head.toString
        hash == pwd
      case _ ⇒ false
    }

  override def authenticate(username: String, password: String)(implicit request: RequestHeader): Future[AuthContext] =
    userSrv.get(username).flatMap { user ⇒
      if (doAuthenticate(user, password)) userSrv.getFromUser(request, user, name)
      else Future.failed(AuthenticationError("Authentication failure"))
    }

  override def changePassword(username: String, oldPassword: String, newPassword: String)(implicit authContext: AuthContext): Future[Unit] =
    userSrv.get(username).flatMap { user ⇒
      if (doAuthenticate(user, oldPassword)) setPassword(username, newPassword)
      else Future.failed(AuthorizationError("Authentication failure"))
    }

  override def setPassword(username: String, newPassword: String)(implicit authContext: AuthContext): Future[Unit] = {
    val seed    = Random.nextString(10).replace(',', '!')
    val newHash = seed + "," + Hasher("SHA-256").fromString(seed + newPassword).head.toString
    userSrv.update(username, Fields.empty.set("password", newHash)).map(_ ⇒ ())
  }
} 
Example 45
Source File: CSRFFilter.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.services

import javax.inject.{Inject, Provider, Singleton}

import play.api.Logger
import play.api.http.SessionConfiguration
import play.api.libs.crypto.CSRFTokenSigner
import play.filters.csrf.{CSRFFilter ⇒ PCSRFFilter}
import play.api.mvc.RequestHeader
import play.filters.csrf.CSRF.{ErrorHandler ⇒ CSRFErrorHandler, TokenProvider}
import play.filters.csrf.CSRFConfig

import akka.stream.Materializer

object CSRFFilter {
  private[CSRFFilter] lazy val logger = Logger(getClass)

  def shouldProtect(request: RequestHeader): Boolean = {
    val isLogin     = request.uri.startsWith("/api/login")
    val isApi       = request.uri.startsWith("/api")
    val isInSession = request.session.data.nonEmpty
    val check       = !isLogin && isApi && isInSession
    logger.debug(s"[csrf] uri ${request.uri} (isLogin=$isLogin, isApi=$isApi, isInSession=$isInSession): ${if (check) "" else "don't"} check")
    check
  }

}

@Singleton
class CSRFFilter @Inject()(
    config: Provider[CSRFConfig],
    tokenSignerProvider: Provider[CSRFTokenSigner],
    sessionConfiguration: SessionConfiguration,
    tokenProvider: TokenProvider,
    errorHandler: CSRFErrorHandler
)(mat: Materializer)
    extends PCSRFFilter(
      config.get.copy(shouldProtect = CSRFFilter.shouldProtect),
      tokenSignerProvider.get,
      sessionConfiguration,
      tokenProvider,
      errorHandler
    )(mat) 
Example 46
Source File: ErrorHandler.scala    From Aton   with GNU General Public License v3.0 5 votes vote down vote up
import com.google.inject.Inject
import play.api.{Application, Play}
import play.api.http.{DefaultHttpErrorHandler, HttpErrorHandler, Status}
import play.api.mvc.{RequestHeader, Result, Results}
import views.html.index

import scala.concurrent.Future


class ErrorHandler @Inject()(errorHandler: DefaultHttpErrorHandler) extends HttpErrorHandler {
  override def onClientError(request: RequestHeader, statusCode: Int, message: String): Future[Result] = {
    statusCode match {
      case clientError if statusCode > 400 && statusCode < 500 => Future.successful(Results.NotFound(index("Aton")))
      case _ => Future.successful(Results.ServiceUnavailable("Unexpected error happened"))
    }
  }

  override def onServerError(request: RequestHeader, exception: Throwable): Future[Result] = {
    errorHandler.onServerError(request,exception)
  }
} 
Example 47
Source File: Versions.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package definition

import play.api.http.HeaderNames.ACCEPT
import play.api.mvc.RequestHeader
import uk.gov.hmrc.http.HeaderCarrier

object Versions {
  val VERSION_1 = "1.0"
  val VERSION_2 = "2.0"

  private val versionRegex = """application\/vnd.hmrc.(\d.\d)\+json""".r

  def getFromRequest(implicit hc: HeaderCarrier): Option[String] =
    getFrom(hc.headers)

  def getFromRequest(request: RequestHeader): Option[String] =
    getFrom(request.headers.headers)

  private def getFrom(headers: Seq[(String, String)]) =
    headers.collectFirst { case (ACCEPT, versionRegex(ver)) => ver }
} 
Example 48
Source File: VersionRoutingRequestHandler.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package routing

import config.{AppConfig, FeatureSwitch}
import definition.Versions
import javax.inject.{Inject, Singleton}
import play.api.http.{DefaultHttpRequestHandler, HttpConfiguration, HttpErrorHandler, HttpFilters}
import play.api.libs.json.Json
import play.api.mvc.{DefaultActionBuilder, Handler, RequestHeader, Results}
import play.api.routing.Router
import v1.controllers.requestParsers.validators.validations.VrnValidation
import v1.models.errors.{InvalidAcceptHeaderError, UnsupportedVersionError, VrnFormatError}

@Singleton
class VersionRoutingRequestHandler @Inject()(versionRoutingMap: VersionRoutingMap,
                                             errorHandler: HttpErrorHandler,
                                             httpConfiguration: HttpConfiguration,
                                             config: AppConfig,
                                             filters: HttpFilters,
                                             action: DefaultActionBuilder)
  extends DefaultHttpRequestHandler(versionRoutingMap.defaultRouter, errorHandler, httpConfiguration, filters) {

  private val featureSwitch = FeatureSwitch(config.featureSwitch)

  private val unsupportedVersionAction = action(Results.NotFound(Json.toJson(UnsupportedVersionError)))

  private val invalidAcceptHeaderError = action(Results.NotAcceptable(Json.toJson(InvalidAcceptHeaderError)))

  override def routeRequest(request: RequestHeader): Option[Handler] = {

    def documentHandler = routeWith(versionRoutingMap.defaultRouter)(request)

    def apiHandler = Versions.getFromRequest(request) match {
      case Some(version) =>
        versionRoutingMap.versionRouter(version) match {
          case Some(versionRouter) if featureSwitch.isVersionEnabled(version) =>
            routeWith(versionRouter)(request)
          case Some(_) => Some(unsupportedVersionAction)
          case None => Some(unsupportedVersionAction)
        }
      case None => Some(invalidAcceptHeaderError)
    }

    documentHandler orElse apiHandler
  }

  private def routeWith(router: Router)(request: RequestHeader) =
    router
      .handlerFor(request)
      .orElse {
        if (validatePath(request.path)) {
          if (request.path.endsWith("/")) {
            val pathWithoutSlash = request.path.dropRight(1)
            val requestWithModifiedPath = request.withTarget(request.target.withPath(pathWithoutSlash))
            router.handlerFor(requestWithModifiedPath)
          }
          else None
        }
        else {
          Some(action(Results.BadRequest(Json.toJson(VrnFormatError))))
        }
      }

  private def validatePath(path: String) = {
    val vrn = path.split("/")(1)
    if(VrnValidation.validate(vrn) == Nil)
      true
    else false
  }
} 
Example 49
Source File: AnyOf.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package org.coursera.naptime.access.authenticator.combiner

import org.coursera.common.concurrent.Futures
import org.coursera.naptime.NaptimeActionException
import org.coursera.naptime.access.authenticator.Authenticator
import play.api.mvc.RequestHeader

import scala.concurrent.ExecutionContext
import scala.concurrent.Future

private[authenticator] trait AnyOf {

  
  def anyOf[A](authenticators: Set[Authenticator[A]]): Authenticator[A] = new Authenticator[A] {

    override def maybeAuthenticate(requestHeader: RequestHeader)(
        implicit ec: ExecutionContext): Future[Option[Either[NaptimeActionException, A]]] = {

      val authenticationResponses = authenticators
        .map(Authenticator.authenticateAndRecover(_, requestHeader))

      val successOptionFuture = Futures.findMatch(authenticationResponses) {
        case Some(Right(authentication)) => Right(authentication)
      }
      lazy val errorOptionFuture = Futures.findMatch(authenticationResponses) {
        case Some(Left(error)) => Left(error)
      }

      Common.combineAuthenticationResponses(successOptionFuture, errorOptionFuture)
    }

  }

  def anyOf[A, A1, A2](authenticator1: Authenticator[A1], authenticator2: Authenticator[A2])(
      implicit transformer1: AuthenticationTransformer[A1, A],
      transformer2: AuthenticationTransformer[A2, A]): Authenticator[A] = {

    anyOf(
      Set(
        authenticator1.collect(transformer1.partial),
        authenticator2.collect(transformer2.partial)))
  }

  def anyOf[A, A1, A2, A3](
      authenticator1: Authenticator[A1],
      authenticator2: Authenticator[A2],
      authenticator3: Authenticator[A3])(
      implicit transformer1: AuthenticationTransformer[A1, A],
      transformer2: AuthenticationTransformer[A2, A],
      transformer3: AuthenticationTransformer[A3, A]): Authenticator[A] = {

    anyOf(
      Set(
        authenticator1.collect(transformer1.partial),
        authenticator2.collect(transformer2.partial),
        authenticator3.collect(transformer3.partial)))
  }

  // TODO(josh): Generate for remaining arities.

} 
Example 50
Source File: PlayParSeq.scala    From play-parseq   with Apache License 2.0 5 votes vote down vote up
package com.linkedin.playparseq.s

import com.linkedin.parseq.{Engine, Task}
import com.linkedin.parseq.promise.Promises
import com.linkedin.playparseq.s.PlayParSeqImplicits._
import com.linkedin.playparseq.s.stores.ParSeqTaskStore
import com.linkedin.playparseq.utils.PlayParSeqHelper
import javax.inject.{Inject, Singleton}
import play.api.mvc.RequestHeader
import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}



  override def runTask[T](task: Task[T])(implicit requestHeader: RequestHeader): Future[T] = {
    // Bind a Future to the ParSeq Task
    val future: Future[T] = bindTaskToFuture(task)
    // Put the ParSeq Task into store
    parSeqTaskStore.put(task)
    // Run the ParSeq Task
    engine.run(task)
    // Return the Future
    future
  }

} 
Example 51
Source File: ParSeqTraceRenderer.scala    From play-parseq   with Apache License 2.0 5 votes vote down vote up
package com.linkedin.playparseq.trace.s.renderers

import com.linkedin.parseq.trace.{ShallowTrace, Trace, TraceRelationship}
import com.linkedin.playparseq.s.stores.ParSeqTaskStore
import com.linkedin.playparseq.trace.utils.ParSeqTraceBaseVisualizer
import javax.inject.{Inject, Singleton}
import play.api.Environment
import play.api.http.HttpConfiguration
import play.api.mvc.{RequestHeader, Result, Results}
import scala.collection.JavaConverters._
import scala.concurrent.{ExecutionContext, Future}



  override def render(parSeqTaskStore: ParSeqTaskStore)(implicit requestHeader: RequestHeader): Future[Result] =
    Future {
      val traces: Set[Trace] = parSeqTaskStore.get.map(_.getTrace)
      val traceMap: Map[java.lang.Long, ShallowTrace] = traces.foldLeft(Map[java.lang.Long, ShallowTrace]())(_ ++ _.getTraceMap.asScala)
      val relationships: Set[TraceRelationship] = traces.foldLeft(Set[TraceRelationship]())(_ ++ _.getRelationships.asScala)
      // Generate Result of ParSeq Trace
      Option(showTrace(new Trace(traceMap.asJava, relationships.asJava), environment, httpConfiguration)).map(Results.Ok(_).as("text/html"))
        .getOrElse(Results.InternalServerError("Can't show Trace."))
    }

} 
Example 52
Source File: Authentication.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package it.gov.daf.common.authentication

import java.util.Date

import com.nimbusds.jwt.JWTClaimsSet
import org.pac4j.core.profile.{CommonProfile, ProfileManager}
import org.pac4j.jwt.config.signature.SecretSignatureConfiguration
import org.pac4j.jwt.credentials.authenticator.JwtAuthenticator
import org.pac4j.jwt.profile.JwtGenerator
import org.pac4j.play.PlayWebContext
import org.pac4j.play.store.PlaySessionStore
import play.api.Configuration
import play.api.mvc.{RequestHeader, Result, Results}

import scala.collection.convert.decorateAsScala._
import scala.collection.mutable

@SuppressWarnings(
  Array(
    "org.wartremover.warts.Throw",
    "org.wartremover.warts.Var"
  )
)
object Authentication extends Results {

  var configuration: Option[Configuration] = None
  var playSessionStore: Option[PlaySessionStore] = None
  var secret: Option[String] = None

  def apply(configuration: Configuration, playSessionStore: PlaySessionStore): Unit = {
    this.configuration = Some(configuration)
    this.playSessionStore = Some(playSessionStore)
    this.secret = this.configuration.flatMap(_.getString("pac4j.jwt_secret"))
  }

  def getClaims(requestHeader: RequestHeader): Option[mutable.Map[String, AnyRef]] = {

    val header: Option[String] = requestHeader.headers.get("Authorization")
    val token: Option[String] = for {
      h <- header
      t <- h.split("Bearer").lastOption
    } yield t.trim

    getClaimsFromToken(token)
  }

  def getClaimsFromToken(token: Option[String]): Option[mutable.Map[String, AnyRef]] = {
    val jwtAuthenticator = new JwtAuthenticator()
    jwtAuthenticator.addSignatureConfiguration(new SecretSignatureConfiguration(secret.getOrElse(throw new Exception("missing secret"))))
    token.map(jwtAuthenticator.validateTokenAndGetClaims(_).asScala)
  }

  def getProfiles(request: RequestHeader): List[CommonProfile] = {
    val webContext = new PlayWebContext(request, playSessionStore.getOrElse(throw new Exception("missing playSessionStore")))
    val profileManager = new ProfileManager[CommonProfile](webContext)
    profileManager.getAll(true).asScala.toList
  }

  def getStringToken: (RequestHeader,Long) => Option[String] = (request: RequestHeader,minutes:Long)  => {
    val generator = new JwtGenerator[CommonProfile](new SecretSignatureConfiguration(secret.getOrElse(throw new Exception("missing secret"))))
    val profiles = getProfiles(request)
    val token: Option[String] = profiles.headOption.map(profile => {
      val expDate = new Date( (new Date).getTime + 1000L*60L*minutes )//*60L*24L
      val claims = new JWTClaimsSet.Builder().expirationTime(expDate).build()
      profile.addAttributes(claims.getClaims)
      generator.generate(profile)
    })
    token
  }

  def getToken: (RequestHeader,Long) => Result = (request: RequestHeader, minutes:Long) => {
    Ok(getStringToken(request,minutes).getOrElse(""))
  }

} 
Example 53
Source File: Utils.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package it.gov.daf.securitymanager.service.utilities


import it.gov.daf.common.sso.common.CacheWrapper
import it.gov.daf.common.utils.{Credentials, Profile}
import play.api.mvc.RequestHeader
import it.gov.daf.common.sso.common.CredentialManager
import scala.util.Try

object Utils {

  def getCredentials( requestHeader: RequestHeader, cacheWrapper:CacheWrapper ):Try[Credentials] = {

    Try{
      CredentialManager.readCredentialFromRequest(requestHeader) match {
        case p:Profile => cacheWrapper.getPwd(p.username) match{
          case Some(pwd) => Credentials(p.username, pwd, p.groups)
          case None => throw new Exception("Can't find credentails in cache")
        }
        case c:Credentials => c
      }
    }

  }

} 
Example 54
Source File: WithSecurityInfoApiHelpController.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package controllers

import io.swagger.config.FilterFactory
import io.swagger.core.filter.SpecFilter
import io.swagger.models.Swagger
import _root_.modules.WithSecurityInfoApiListingCache
import play.api.Logger
import play.api.mvc.RequestHeader

import scala.collection.JavaConverters._

@SuppressWarnings(
  Array(
    "org.wartremover.warts.ImplicitParameter"
  )
)
class WithSecurityInfoApiHelpController extends ApiHelpController {
  override protected def getResourceListing(host: String)(implicit requestHeader: RequestHeader): Swagger = {
    Logger("swagger").debug("ApiHelpInventory.getRootResources")
    val docRoot = ""
    val queryParams = for ((key, value) <- requestHeader.queryString) yield {
      (key, value.toList.asJava)
    }
    val cookies = (for (cookie <- requestHeader.cookies) yield {
      (cookie.name, cookie.value)
    }).toMap
    val headers = for ((key, value) <- requestHeader.headers.toMap) yield {
      (key, value.toList.asJava)
    }

    val f = new SpecFilter
    val l: Option[Swagger] = WithSecurityInfoApiListingCache.listing(docRoot, host)

    val specs: Swagger = l match {
      case Some(m) => m
      case _ => new Swagger()
    }

    val hasFilter = Option(FilterFactory.getFilter)
    hasFilter match {
      case Some(_) => f.filter(specs, FilterFactory.getFilter, queryParams.asJava, cookies.asJava, headers.asJava)
      case None => specs
    }
  }

  override protected def getApiListing(resourceName: String, host: String)(implicit requestHeader: RequestHeader): Swagger = {
    Logger("swagger").debug("ApiHelpInventory.getResource(%s)".format(resourceName))
    val docRoot = ""
    val f = new SpecFilter
    val queryParams = requestHeader.queryString.map {case (key, value) => key -> value.toList.asJava}
    val cookies = requestHeader.cookies.map {cookie => cookie.name -> cookie.value}.toMap.asJava
    val headers = requestHeader.headers.toMap.map {case (key, value) => key -> value.toList.asJava}
    val pathPart = resourceName

    val l: Option[Swagger] = WithSecurityInfoApiListingCache.listing(docRoot, host)
    val specs: Swagger = l match {
      case Some(m) => m
      case _ => new Swagger()
    }
    val hasFilter = Option(FilterFactory.getFilter)

    val clone = hasFilter match {
      case Some(_) => f.filter(specs, FilterFactory.getFilter, queryParams.asJava, cookies, headers.asJava)
      case None => specs
    }
    clone.setPaths(clone.getPaths.asScala.filterKeys(_.startsWith(pathPart)).asJava)
    clone
  }
} 
Example 55
Source File: FormPartialService.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package services.partials

import com.google.inject.{Inject, Singleton}
import com.kenshoo.play.metrics.Metrics
import config.ConfigDecorator
import metrics.HasMetrics
import play.api.Mode.Mode
import play.api.mvc.RequestHeader
import play.api.{Configuration, Environment}
import uk.gov.hmrc.play.bootstrap.config.ServicesConfig
import uk.gov.hmrc.play.bootstrap.filters.frontend.crypto.SessionCookieCrypto
import uk.gov.hmrc.play.bootstrap.http.HttpClient
import uk.gov.hmrc.play.partials.HtmlPartial
import util.EnhancedPartialRetriever

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class FormPartialService @Inject()(
  environment: Environment,
  runModeConfiguration: Configuration,
  override val http: HttpClient,
  val metrics: Metrics,
  val configDecorator: ConfigDecorator,
  sessionCookieCrypto: SessionCookieCrypto,
  servicesConfig: ServicesConfig)(implicit executionContext: ExecutionContext)
    extends EnhancedPartialRetriever(sessionCookieCrypto) with HasMetrics {

  val mode: Mode = environment.mode
  def getNationalInsurancePartial(implicit request: RequestHeader): Future[HtmlPartial] =
    loadPartial(configDecorator.nationalInsuranceFormPartialLinkUrl)

  def getSelfAssessmentPartial(implicit request: RequestHeader): Future[HtmlPartial] =
    loadPartial(configDecorator.selfAssessmentFormPartialLinkUrl)

} 
Example 56
Source File: PreferencesFrontendPartialService.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package services.partials

import com.google.inject.{Inject, Singleton}
import com.kenshoo.play.metrics.Metrics
import metrics.HasMetrics
import play.api.Mode.Mode
import play.api.mvc.RequestHeader
import play.api.{Configuration, Environment}
import uk.gov.hmrc.play.bootstrap.config.ServicesConfig
import uk.gov.hmrc.play.bootstrap.filters.frontend.crypto.SessionCookieCrypto
import uk.gov.hmrc.play.bootstrap.http.HttpClient
import uk.gov.hmrc.play.partials.HtmlPartial
import util.{EnhancedPartialRetriever, Tools}

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class PreferencesFrontendPartialService @Inject()(
  environment: Environment,
  runModeConfiguration: Configuration,
  val http: HttpClient,
  val metrics: Metrics,
  sessionCookieCrypto: SessionCookieCrypto,
  val tools: Tools,
  servicesConfig: ServicesConfig)(implicit executionContext: ExecutionContext)
    extends EnhancedPartialRetriever(sessionCookieCrypto) with HasMetrics {

  val mode: Mode = environment.mode
  val preferencesFrontendUrl = servicesConfig.baseUrl("preferences-frontend")

  def getManagePreferencesPartial(returnUrl: String, returnLinkText: String)(
    implicit request: RequestHeader): Future[HtmlPartial] =
    loadPartial(s"$preferencesFrontendUrl/paperless/manage?returnUrl=${tools
      .encryptAndEncode(returnUrl)}&returnLinkText=${tools.encryptAndEncode(returnLinkText)}")

} 
Example 57
Source File: MessageFrontendService.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package services.partials

import com.google.inject.{Inject, Singleton}
import com.kenshoo.play.metrics.Metrics
import metrics.HasMetrics
import models.MessageCount
import play.api.Mode.Mode
import play.api.mvc.RequestHeader
import play.api.{Configuration, Environment, Logger}
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.play.bootstrap.config.ServicesConfig
import uk.gov.hmrc.play.bootstrap.filters.frontend.crypto.SessionCookieCrypto
import uk.gov.hmrc.play.bootstrap.http.HttpClient
import uk.gov.hmrc.play.partials.HtmlPartial
import util.EnhancedPartialRetriever

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class MessageFrontendService @Inject()(
  environment: Environment,
  runModeConfiguration: Configuration,
  override val http: HttpClient,
  val metrics: Metrics,
  val sessionCookieCrypto: SessionCookieCrypto,
  servicesConfig: ServicesConfig)(implicit executionContext: ExecutionContext)
    extends EnhancedPartialRetriever(sessionCookieCrypto) with HasMetrics {

  val mode: Mode = environment.mode

  lazy val messageFrontendUrl: String = servicesConfig.baseUrl("message-frontend")

  def getMessageListPartial(implicit request: RequestHeader): Future[HtmlPartial] =
    loadPartial(messageFrontendUrl + "/messages")

  def getMessageDetailPartial(messageToken: String)(implicit request: RequestHeader): Future[HtmlPartial] =
    loadPartial(messageFrontendUrl + "/messages/" + messageToken)

  def getMessageInboxLinkPartial(implicit request: RequestHeader): Future[HtmlPartial] =
    loadPartial(
      messageFrontendUrl + "/messages/inbox-link?messagesInboxUrl=" + controllers.routes.MessageController
        .messageList())

  def getUnreadMessageCount(implicit request: RequestHeader): Future[Option[Int]] =
    loadJson(messageFrontendUrl + "/messages/count?read=No").map(_.map(_.count))

  private def loadJson(url: String)(implicit hc: HeaderCarrier): Future[Option[MessageCount]] =
    withMetricsTimer("load-json") { t =>
      http.GET[Option[MessageCount]](url) recover {
        case e =>
          t.completeTimerAndIncrementFailedCounter()
          Logger.warn(s"Failed to load json", e)
          None
      }
    }
} 
Example 58
Source File: ErrorHandler.scala    From akka-http-test   with Apache License 2.0 5 votes vote down vote up
import javax.inject._

import play.api._
import play.api.http.DefaultHttpErrorHandler
import play.api.libs.json.Json
import play.api.mvc.Results._
import play.api.mvc.{ RequestHeader, Result }
import play.api.routing.Router

import scala.concurrent.Future

@Singleton
class ErrorHandler @Inject() (env: Environment, config: Configuration, sourceMapper: OptionalSourceMapper, router: Provider[Router]) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {
  override protected def onNotFound(request: RequestHeader, message: String): Future[Result] = {
    Future.successful(NotFound(Json.obj("path" -> request.path, "messages" -> List("not found", message))))
  }

  override protected def onDevServerError(request: RequestHeader, exception: UsefulException): Future[Result] = {
    Future.successful(InternalServerError(Json.obj("path" -> request.path, "messages" -> List(exception.description))))
  }

  override protected def onProdServerError(request: RequestHeader, exception: UsefulException): Future[Result] = {
    Future.successful(InternalServerError(Json.obj("path" -> request.path, "messages" -> List(exception.description))))
  }

  override protected def onForbidden(request: RequestHeader, message: String): Future[Result] = {
    Future.successful(Forbidden(Json.obj("path" -> request.path, "messages" -> List("forbidden", message))))
  }
} 
Example 59
Source File: simple_petstore_api_yaml.scala    From play-swagger   with MIT License 5 votes vote down vote up
package simple_petstore_api_yaml

import play.api.http.Writeable
import play.api.libs.iteratee.Execution.Implicits.trampoline
import play.api.mvc.RequestHeader
import de.zalando.play.controllers._
import WriteableWrapper.writeable2wrapper

import de.zalando.play.controllers.ArrayWrapper




    override val custom: Seq[WriteableWrapper[_]] = Seq(
        writable_text_xml_PetsGetResponses200_esc, 
        writable_text_html_PetsGetResponses200_esc, 
        writable_application_xml_PetsGetResponses200_esc, 
        writable_application_xml_ErrorModel_esc, 
        writable_text_html_ErrorModel_esc, 
        writable_text_xml_ErrorModel_esc, 
        writable_application_xml_Pet_esc, 
        writable_text_html_Pet_esc, 
        writable_text_xml_Pet_esc
    )
} 
Example 60
Source File: writableHelperTest.scala    From play-swagger   with MIT License 5 votes vote down vote up
package de.zalando.play.controllers

import de.zalando.play.controllers.ResponseWriters.choose
import org.specs2.mutable.Specification
import play.api.http.Writeable
import play.api.mvc.RequestHeader
import scala.concurrent.ExecutionContext.Implicits


    override val custom: Seq[(String, ParserWrapper[_])] = Seq(
      "text/plain" -> any
    )
  }

  "WrappedBodyParsers" should {
    "find something" in {
      WrappedBodyParsers.anyParser[Any] must_== Nil
    }
    "not find anything for wrong type" in {
      binaryString.anyParser[String] must_== Nil
    }
    "find something for correct type" in {
      binaryString.anyParser[BinaryString].size must_== 1
    }
    "find something for every type if target is 'Any'" in {
      catchAll.anyParser[String].size must_== 1
      catchAll.anyParser[BinaryString].size must_== 1
    }
  }
}

object TestEnvironment {
  import Implicits.global
  val transformSeq: Seq[Any] => Array[Byte] = a => a.toString.getBytes("UTF-8")
  val transformStr: String => Array[Byte] = a => a.getBytes("UTF-8")

  val seqText: WriteableWrapper[Seq[Any]] = Writeable(transformSeq, Some("text/plain"))

  val stringText: WriteableWrapper[String] = Writeable(transformStr, Some("text/plain"))

  val reg = Seq(seqText, stringText)
} 
Example 61
Source File: writeableHelper.scala    From play-swagger   with MIT License 5 votes vote down vote up
package de.zalando.play.controllers

import play.api.http.Writeable
import play.api.mvc.{AnyContentAsMultipartFormData, RequestHeader}
import scala.language.implicitConversions
import play.api.mvc.{RequestHeader, Result, Results}
import play.api.http._
import Results.{Status, Redirect}

case class WriteableWrapper[T](w: Writeable[T], m: Manifest[T])

object WriteableWrapper {
  implicit def writeable2wrapper[T](w: Writeable[T])(implicit m: Manifest[T]) =
    WriteableWrapper(w, m)
  implicit val anyContentAsMultipartFormWritable: Writeable[AnyContentAsMultipartFormData] = {
    MultipartFormDataWritable.singleton.map(_.mdf)
  }
}


object ResponseWriters extends ResponseWritersBase

trait ResponseWritersBase {

  type ContentType = String

  def custom: Seq[WriteableWrapper[_]] = Seq.empty

  case class choose[T](mimeType: ContentType) {
    def apply[R <: Any](registry: Seq[WriteableWrapper[_]] = custom)(implicit m: Manifest[R]): Option[Writeable[R]] =
      registry filter {
        _.w.contentType.exists(_ == mimeType)
      } find { p =>
        m.runtimeClass.isAssignableFrom(p.m.runtimeClass)
      } map  {
        _.asInstanceOf[WriteableWrapper[R]]
      } map(_.w)
  }

}

object WrappedBodyParsers extends WrappedBodyParsersBase

trait WrappedBodyParsersBase {
  implicit def parser2parserWrapper[T](p: Parser[T])(implicit m: Manifest[T]): ParserWrapper[T] = ParserWrapper(p, m)
  type Parser[T] = (RequestHeader, Array[Byte]) => T
  case class ParserWrapper[T](p: Parser[T], m: Manifest[T])
  val custom: Seq[(String, ParserWrapper[_])] = Seq.empty
  def anyParser[T](implicit manifest: Manifest[T]): Seq[(String, Parser[T])] =
    custom.filter(_._2.m.runtimeClass.isAssignableFrom(manifest.runtimeClass)).map { e =>
      e.copy(_2 = e._2.asInstanceOf[ParserWrapper[T]].p) }
  def optionParser[T](implicit manifest: Manifest[T]): Seq[(String, Parser[Option[T]])] = anyParser[Option[T]]
}

trait ResultWrapper[ResultT] {
  def statusCode: Int
  def result: ResultT
  def writer: String => Option[Writeable[ResultT]]
  def toResult(mimeType: String): Option[play.api.mvc.Result] =
    if (statusCode / 100 == 3)
      Option(Redirect(result.toString, statusCode))
    else
      writer(mimeType).map(Status(statusCode)(result)(_))
} 
Example 62
Source File: JwtAuthenticator.scala    From scala-play-realworld-example-app   with MIT License 5 votes vote down vote up
package authentication.jwt.services

import authentication.exceptions._
import authentication.models.SecurityUserId
import commons.repositories.DateTimeProvider
import io.jsonwebtoken._
import play.api.mvc.RequestHeader
import play.mvc.Http

class JwtAuthenticator(dateTimeProvider: DateTimeProvider,
                                secretProvider: SecretProvider) {

  def authenticate(requestHeader: RequestHeader): Either[AuthenticationExceptionCode, (SecurityUserId, String)] = {
    requestHeader.headers.get(Http.HeaderNames.AUTHORIZATION)
      .map(parse)
      .toRight(MissingOrInvalidCredentialsCode)
      .flatMap(validate)
  }

  private def expirationIsMissing(jwt: Jws[Claims]): Boolean = {
    jwt.getBody.getExpiration == null
  }

  private def validate(rawToken: String) = {
    try {
      val jwt = Jwts.parser()
        .setSigningKey(secretProvider.get)
        .parseClaimsJws(rawToken)

      if (expirationIsMissing(jwt)) Left(MissingOrInvalidCredentialsCode)
      else if (isNotExpired(jwt)) Right((getSecurityUserId(jwt), rawToken))
      else Left(ExpiredCredentialsCode)
    } catch {
      case _: JwtException =>
        Left(MissingOrInvalidCredentialsCode)
    }
  }

  private def parse(authorizationHeader: String) = {
    authorizationHeader.stripPrefix("Token ")
  }

  private def getSecurityUserId(jwt: Jws[Claims]) = {
    val securityUserId = java.lang.Long.parseLong(jwt.getBody.get(JwtTokenGenerator.securityUserIdClaimName, classOf[String]))
    SecurityUserId(securityUserId)
  }

  private def isNotExpired(jwt: Jws[Claims]) = {
    val expiration = jwt.getBody.getExpiration.toInstant

    dateTimeProvider.now.isBefore(expiration)
  }

} 
Example 63
Source File: Versions.scala    From self-assessment-api   with Apache License 2.0 5 votes vote down vote up
package router.constants

import play.api.http.HeaderNames.ACCEPT
import play.api.mvc.RequestHeader
import uk.gov.hmrc.http.HeaderCarrier

object Versions {
  val VERSION_1 = "1.0"
  val VERSION_2 = "2.0"

  private val versionRegex = """application\/vnd.hmrc.(\d.\d)\+json""".r

  def getFromRequest(implicit hc: HeaderCarrier): Option[String] =
    getFrom(hc.headers)

  def getFromRequest(request: RequestHeader): Option[String] =
    getFrom(request.headers.headers)

  private def getFrom(headers: Seq[(String, String)]) =
    headers.collectFirst { case (ACCEPT, versionRegex(ver)) => ver }
} 
Example 64
Source File: JsonEntities.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package endpoints4s.play.server

import akka.util.ByteString
import endpoints4s.{Codec, Decoder, Encoder, Invalid, algebra}
import play.api.mvc.RequestHeader
import play.api.http.{ContentTypes, Writeable}


trait JsonEntitiesFromEncodersAndDecoders
    extends algebra.JsonEntities
    with EndpointsWithCustomErrors {

  type JsonResponse[A] = Encoder[A, String]
  type JsonRequest[A] = Decoder[String, A]

  def jsonRequest[A](implicit decoder: JsonRequest[A]): RequestEntity[A] =
    JsonEntities.decodeRequest(this)(decoder)

  def jsonResponse[A](implicit encoder: JsonResponse[A]): ResponseEntity[A] =
    responseEntityFromWriteable(JsonEntities.encodeResponse(encoder))

}

private object JsonEntities {

  def decodeRequest[A](
      endpoints: EndpointsWithCustomErrors
  )(decoder: Decoder[String, A]): endpoints.RequestEntity[A] =
    (request: RequestHeader) => {
      if (request.contentType.exists(_.equalsIgnoreCase("application/json"))) {
        val decodeJson = (bs: ByteString) =>
          decoder
            .decode(bs.utf8String)
            .toEither
            .left
            .map(errs => endpoints.handleClientErrors(Invalid(errs)))

        val bodyParser =
          endpoints.playComponents.playBodyParsers.byteString
            .validate(decodeJson)(endpoints.playComponents.executionContext)
        Some(bodyParser)
      } else {
        None
      }
    }

  def encodeResponse[A](encoder: Encoder[A, String]): Writeable[A] =
    Writeable(a => ByteString(encoder.encode(a)), Some(ContentTypes.JSON))

} 
Example 65
Source File: SecurityRulesRepository.scala    From play-zhewbacca   with MIT License 5 votes vote down vote up
package org.zalando.zhewbacca

import javax.inject.Inject

import com.typesafe.config.{Config, ConfigFactory}
import play.api.{Configuration, Logger}
import scala.collection.JavaConverters._

import play.api.http.HttpVerbs._
import play.api.mvc.RequestHeader

class SecurityRulesRepository @Inject() (configuration: Configuration, provider: AuthProvider) {

  private val logger = Logger(getClass)

  private val SupportedHttpMethods: Set[String] = Set(GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)

  private val ConfigKeyMethod = "method"
  private val ConfigKeyPathRegex = "pathRegex"
  private val ConfigKeyScopes = "scopes"
  private val ConfigKeyAllowed = "allowed"
  private val ConfigKeyRules = "rules"

  private val rules: Seq[StrictRule] = load()

  def get(requestHeader: RequestHeader): Option[StrictRule] =
    rules.find(_.isApplicableTo(requestHeader))

  private def load(): Seq[StrictRule] = {
    val securityRulesFileName = configuration.getOptional[String]("authorisation.rules.file").getOrElse("security_rules.conf")
    logger.info(s"Configuration file for security rules: $securityRulesFileName")

    if (configFileExists(securityRulesFileName)) {
      ConfigFactory.load(securityRulesFileName)
        .getConfigList(ConfigKeyRules).asScala
        .map(toRule)
    } else {
      sys.error(s"configuration file $securityRulesFileName for security rules not found")
    }
  }

  private def toRule(config: Config): StrictRule = {
    (getHttpMethod(config), config.getString(ConfigKeyPathRegex), getAllowedFlag(config), getScopeNames(config)) match {
      case (Some(method), pathRegex, Some(true), _) =>
        logger.info(s"Explicitly allowed unauthorized requests for method: '$method' and path regex: '$pathRegex'")
        ExplicitlyAllowedRule(method, pathRegex)

      case (Some(method), pathRegex, Some(false), _) =>
        logger.info(s"Explicitly denied all requests for method: '$method' and path regex: '$pathRegex'")
        ExplicitlyDeniedRule(method, pathRegex)

      case (Some(method), pathRegex, None, Some(scopeNames)) =>
        logger.info(s"Configured required scopes '$scopeNames' for method '$method' and path regex: '$pathRegex'")
        ValidateTokenRule(provider, method, pathRegex, Scope(scopeNames))

      case _ =>
        sys.error(s"Invalid config: $config")
    }
  }

  private def configFileExists(fileName: String): Boolean =
    Option(Thread.currentThread()
      .getContextClassLoader
      .getResource(fileName))
      .isDefined

  private def getHttpMethod(config: Config): Option[String] = {
    if (SupportedHttpMethods(config.getString(ConfigKeyMethod))) {
      Some(config.getString(ConfigKeyMethod))
    } else {
      None
    }
  }

  private def getAllowedFlag(config: Config): Option[Boolean] = {
    if (config.hasPath(ConfigKeyAllowed)) {
      Some(config.getBoolean(ConfigKeyAllowed))
    } else {
      None
    }
  }

  private def getScopeNames(config: Config): Option[Set[String]] = {
    if (config.hasPath(ConfigKeyScopes)) {
      Some(config.getStringList(ConfigKeyScopes).asScala.toSet)
    } else {
      None
    }
  }

} 
Example 66
Source File: TokenInfoConverter.scala    From play-zhewbacca   with MIT License 5 votes vote down vote up
package org.zalando.zhewbacca

import play.api.libs.typedmap.TypedKey
import play.api.mvc.RequestHeader

object TokenInfoConverter {

  private val AccessTokenKey: TypedKey[String] = TypedKey("tokenInfo.access_token")
  private val ScopeKey: TypedKey[String] = TypedKey("tokenInfo.scope")
  private val ScopeSeparator = '|'
  private val TokenTypeKey: TypedKey[String] = TypedKey("tokenInfo.token_type")
  private val UidKey: TypedKey[String] = TypedKey("tokenInfo.uid")
  private val ClientIdKey: TypedKey[Option[String]] = TypedKey("tokenInfo.client_id")
  private val RealmKey: TypedKey[String] = TypedKey("tokenInfo.realm")

  implicit class AuthenticatedRequestHeader(underlying: RequestHeader) {

    def tokenInfo: TokenInfo = {
      val accessToken = underlying.attrs.get(AccessTokenKey).getOrElse(sys.error("access token not provided"))
      val scopeNames = underlying.attrs.get(ScopeKey).getOrElse(sys.error("scope not provided"))
        .split(ScopeSeparator)
        .toSet
      val tokenType = underlying.attrs.get(TokenTypeKey).getOrElse(sys.error("token type is not provided"))
      val uid = underlying.attrs.get(UidKey).getOrElse(sys.error("user id is not provided"))
      val clientId = underlying.attrs.get(ClientIdKey).flatten
      val realm = underlying.attrs.get(RealmKey).getOrElse(sys.error("realm is not provided"))

      TokenInfo(accessToken, Scope(scopeNames), tokenType, uid, clientId, realm)
    }

    private[zhewbacca] def withTokenInfo(tok: TokenInfo): RequestHeader = {
      underlying
        .addAttr(AccessTokenKey, tok.accessToken)
        .addAttr(ScopeKey, tok.scope.names.mkString(ScopeSeparator.toString))
        .addAttr(TokenTypeKey, tok.tokenType)
        .addAttr(UidKey, tok.userUid)
        .addAttr(ClientIdKey, tok.clientId)
        .addAttr(RealmKey, tok.realm)
    }
  }

} 
Example 67
Source File: SecurityRule.scala    From play-zhewbacca   with MIT License 5 votes vote down vote up
package org.zalando.zhewbacca

import org.zalando.zhewbacca.TokenInfoConverter._
import play.api.Logger
import play.api.mvc.{RequestHeader, Result, Results}

import scala.concurrent.{ExecutionContext, Future}

trait SecurityRule {
  def isApplicableTo(requestHeader: RequestHeader): Boolean
  def execute(nextFilter: RequestHeader => Future[Result], requestHeader: RequestHeader)(implicit ec: ExecutionContext): Future[Result]
}

abstract class StrictRule(method: String, pathRegex: String) extends SecurityRule {

  private val RequestMatcherRegex = s"^$method $pathRegex$$".r

  def isApplicableTo(requestHeader: RequestHeader): Boolean =
    RequestMatcherRegex.pattern.matcher(s"${requestHeader.method} ${requestHeader.uri}").matches

}

case class ValidateTokenRule(
    authProvider: AuthProvider,
    method: String,
    pathRegex: String,
    scope: Scope) extends StrictRule(method, pathRegex) {

  private[this] val log = Logger(this.getClass)

  override def execute(nextFilter: RequestHeader => Future[Result], requestHeader: RequestHeader)(implicit ec: ExecutionContext): Future[Result] =
    RequestValidator.validate(scope, requestHeader, authProvider).flatMap[Result] {
      case Right(tokenInfo) =>
        log.info(s"Request #${requestHeader.id} authenticated as: ${tokenInfo.userUid}")
        nextFilter(requestHeader.withTokenInfo(tokenInfo))

      case Left(result) =>
        log.info(s"Request #${requestHeader.id} failed auth")
        Future.successful(result)
    }
}


case object DenyAllRule extends DenySecurityRule {
  override def isApplicableTo(requestHeader: RequestHeader): Boolean = true
}

trait DenySecurityRule extends SecurityRule {
  override def execute(nextFilter: RequestHeader => Future[Result], requestHeader: RequestHeader)(implicit ec: ExecutionContext): Future[Result] =
    Future.successful(Results.Forbidden)
} 
Example 68
Source File: SaPartialService.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package services.partials

import com.google.inject.{Inject, Singleton}
import com.kenshoo.play.metrics.Metrics
import config.ConfigDecorator
import metrics.HasMetrics
import play.api.Mode.Mode
import play.api.mvc.RequestHeader
import play.api.{Configuration, Environment}
import uk.gov.hmrc.play.bootstrap.config.ServicesConfig
import uk.gov.hmrc.play.bootstrap.filters.frontend.crypto.SessionCookieCrypto
import uk.gov.hmrc.play.bootstrap.http.HttpClient
import uk.gov.hmrc.play.partials.HtmlPartial
import util.{EnhancedPartialRetriever, Tools}

import scala.concurrent.{ExecutionContext, Future}
@Singleton
class SaPartialService @Inject()(
  environment: Environment,
  runModeConfiguration: Configuration,
  override val http: HttpClient,
  val metrics: Metrics,
  val configDecorator: ConfigDecorator,
  sessionCookieCrypto: SessionCookieCrypto,
  val tools: Tools,
  servicesConfig: ServicesConfig)(implicit executionContext: ExecutionContext)
    extends EnhancedPartialRetriever(sessionCookieCrypto) with HasMetrics {

  val mode: Mode = environment.mode
  private val returnUrl = configDecorator.pertaxFrontendHomeUrl
  private val returnLinkText = configDecorator.saPartialReturnLinkText

  def getSaAccountSummary(implicit request: RequestHeader): Future[HtmlPartial] =
    loadPartial(
      configDecorator.businessTaxAccountService + s"/business-account/partial/sa/account-summary?returnUrl=${tools
        .urlEncode(returnUrl)}&returnLinkText=${tools.urlEncode(returnLinkText)}")

} 
Example 69
Source File: NaptimePlayRouterTest.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package org.coursera.naptime.router2

import akka.util.ByteString
import com.google.inject.Injector
import org.coursera.naptime.resources.RootResource
import org.coursera.naptime.schema.Handler
import org.coursera.naptime.schema.HandlerKind
import org.coursera.naptime.schema.Parameter
import org.coursera.naptime.schema.Resource
import org.coursera.naptime.schema.ResourceKind
import org.junit.Test
import org.mockito.Mockito.when
import org.mockito.Matchers.any
import org.scalatest.junit.AssertionsForJUnit
import org.scalatest.mockito.MockitoSugar
import play.api.libs.streams.Accumulator
import play.api.mvc.EssentialAction
import play.api.mvc.RequestHeader
import play.api.mvc.RequestTaggingHandler
import play.api.mvc.Result
import play.api.test.FakeRequest

class NaptimePlayRouterTest extends AssertionsForJUnit with MockitoSugar {
  object FakeHandler extends  EssentialAction with RequestTaggingHandler {
    override def tagRequest(request: RequestHeader): RequestHeader = request

    override def apply(v1: RequestHeader): Accumulator[ByteString, Result] = ???
  }

  val resourceSchema = Resource(
    kind = ResourceKind.COLLECTION,
    name = "fakeResource",
    version = Some(1L),
    parentClass = Some(classOf[RootResource].getName),
    keyType = "java.lang.String",
    valueType = "FakeModel",
    mergedType = "FakeResourceModel",
    handlers = List(
      Handler(
        kind = HandlerKind.GET,
        name = "get",
        parameters =
          List(Parameter(name = "id", `type` = "String", attributes = List.empty, default = None)),
        inputBodyType = None,
        customOutputBodyType = None,
        attributes = List.empty)),
    className = "org.coursera.naptime.FakeResource",
    attributes = List.empty)

  val resourceRouter = mock[ResourceRouter]
  val resourceRouterBuilder = mock[ResourceRouterBuilder]
  when(resourceRouterBuilder.build(any())).thenReturn(resourceRouter)
  when(resourceRouterBuilder.schema).thenReturn(resourceSchema)

  val injector = mock[Injector]
  val naptimeRoutes = NaptimeRoutes(injector, Set(resourceRouterBuilder))
  val router = new NaptimePlayRouter(naptimeRoutes)

  @Test
  def simpleRouting(): Unit = {
    when(resourceRouter.routeRequest(any(), any())).thenReturn(Some(FakeHandler))
    val handler = router.handlerFor(FakeRequest())
    assert(handler.isDefined)
  }

  @Test
  def simpleRoutingNothing(): Unit = {
    when(resourceRouter.routeRequest(any(), any())).thenReturn(None)
    val handler = router.handlerFor(FakeRequest())
    assert(handler.isEmpty)
  }

  @Test
  def generateDocumentation(): Unit = {
    val documentation = router.documentation
    assert(1 === documentation.length)
    assert(
      (
        "GET --- GET",
        "/fakeResource.v1/$id",
        "[NAPTIME] org.coursera.naptime.FakeResource.get(id: String)") ===
        documentation.head)
  }
} 
Example 70
Source File: Router.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package org.coursera.naptime.router2

import javax.inject.Inject

import com.google.inject.Injector
import org.coursera.naptime.resources.CollectionResource
import play.api.mvc.RequestHeader

import scala.annotation.tailrec
import scala.collection.immutable
import language.experimental.macros

object Router {
  def build[T <: CollectionResource[_, _, _]]: ResourceRouterBuilder = macro MacroImpls.build[T]

  
      @tailrec
      def routeRequestHelper(
          resourceRouters: Seq[ResourceRouter],
          requestHeader: RequestHeader,
          path: String): Option[RouteAction] = {
        if (resourceRouters.isEmpty) {
          None
        } else {
          val first = resourceRouters.head
          val firstResult = first.routeRequest(path, requestHeader)
          if (firstResult.isDefined) {
            firstResult
          } else {
            routeRequestHelper(resourceRouters.tail, requestHeader, path)
          }
        }
      }

      routeRequestHelper(resourceRouters, requestHeader, path)
    } else {
      None
    }
  }

  // TODO(saeta): add additional functionality (i.e. listing all resources / metadata, etc.)

  // TODO(saeta): performance test the new router implementation & do reasonable optimizations.
} 
Example 71
Source File: CourierQueryParsers.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package org.coursera.naptime.router2

import java.io.IOException

import com.linkedin.data.DataMap
import com.linkedin.data.schema.DataSchema
import com.linkedin.data.schema.validation.CoercionMode
import com.linkedin.data.schema.validation.RequiredMode
import com.linkedin.data.schema.validation.ValidateDataAgainstSchema
import com.linkedin.data.schema.validation.ValidationOptions
import com.typesafe.scalalogging.StrictLogging
import org.coursera.courier.codecs.InlineStringCodec
import org.coursera.naptime.courier.StringKeyCodec
import play.api.mvc.RequestHeader

object CourierQueryParsers extends StrictLogging {

  import CollectionResourceRouter.errorRoute

  private[this] val validationOptions =
    new ValidationOptions(RequiredMode.FIXUP_ABSENT_WITH_DEFAULT, CoercionMode.STRING_TO_PRIMITIVE)

  private[this] def parseStringToDataMap(
      paramName: String,
      schema: DataSchema,
      resourceClass: Class[_])(value: String): Either[RouteAction, DataMap] = {
    try {
      val parsed = if (value.startsWith("(") && value.endsWith(")")) {
        InlineStringCodec.instance.bytesToMap(value.getBytes("UTF-8"))
      } else {
        val codec = new StringKeyCodec(schema)
        codec.bytesToMap(value.getBytes("UTF-8"))
      }
      val validated = ValidateDataAgainstSchema.validate(parsed, schema, validationOptions)
      if (validated.isValid) {
        Right(validated.getFixed.asInstanceOf[DataMap])
      } else {
        logger.warn(
          s"${resourceClass.getName}: Bad query parameter for parameter " +
            s"'$paramName': $value. Errors: ${validated.getMessages}")
        Left(errorRoute(s"Improperly formatted value for parameter '$paramName'", resourceClass))
      }
    } catch {
      case ioException: IOException =>
        logger.warn(
          s"${resourceClass.getName}: Bad query parameter for parameter " +
            s"'$paramName': $value. Errors: ${ioException.getMessage}")
        Left(errorRoute(s"Improperly formatted value for parameter '$paramName'", resourceClass))
    }
  }

  def strictParse(
      paramName: String,
      schema: DataSchema,
      resourceClass: Class[_],
      rh: RequestHeader): Either[RouteAction, DataMap] = {
    val queryStringResults = rh.queryString.get(paramName)
    if (queryStringResults.isEmpty || queryStringResults.get.isEmpty) {
      Left(errorRoute(s"Missing required parameter '$paramName'", resourceClass))
    } else if (queryStringResults.get.tail.isEmpty) {
      val stringValue = queryStringResults.get.head
      parseStringToDataMap(paramName, schema, resourceClass)(stringValue)
    } else {
      Left(errorRoute(s"Too many query parameters for '$paramName", resourceClass))
    }
  }

  def optParse(
      paramName: String,
      schema: DataSchema,
      resourceClass: Class[_],
      rh: RequestHeader): Either[RouteAction, Option[DataMap]] = {
    val queryStringResults = rh.queryString.get(paramName)
    if (queryStringResults.isEmpty || queryStringResults.get.isEmpty) {
      Right(None)
    } else if (queryStringResults.get.tail.isEmpty) {
      val stringValue = queryStringResults.get.head
      parseStringToDataMap(paramName, schema, resourceClass)(stringValue).right.map(Some(_))
    } else {
      Left(errorRoute(s"Too many query parameters for '$paramName", resourceClass))
    }
  }

  // TODO: Add a 'QTry' query parameter type that will attempt to parse the query parameter but
  // instead of failing, will provide the valiation errors to the resource handler to do with what
  // they want.
} 
Example 72
Source File: EitherOf.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package org.coursera.naptime.access.combiner

import org.coursera.common.concurrent.Futures
import org.coursera.naptime.NaptimeActionException
import org.coursera.naptime.access.HeaderAccessControl
import play.api.mvc.RequestHeader

import scala.concurrent.ExecutionContext
import scala.concurrent.Future

private[access] trait EitherOf {

  
  def eitherOf[A, B](
      controlA: HeaderAccessControl[A],
      controlB: HeaderAccessControl[B]): HeaderAccessControl[Either[A, B]] = {

    new HeaderAccessControl[Either[A, B]] {
      override def run(requestHeader: RequestHeader)(
          implicit ec: ExecutionContext): Future[Either[NaptimeActionException, Either[A, B]]] = {

        val futureA = Futures.safelyCall(controlA.run(requestHeader))
        val futureB = Futures.safelyCall(controlB.run(requestHeader))

        for {
          resultA <- futureA
          resultB <- futureB
        } yield {
          (resultA, resultB) match {
            case (_, Right(authentication)) => Right(Right(authentication))
            case (Right(authentication), _) => Right(Left(authentication))
            case (_, Left(error))           => Left(error)
            case (Left(error), _)           => Left(error)
          }
        }
      }

      override private[naptime] def check(
          authInfo: Either[A, B]): Either[NaptimeActionException, Either[A, B]] = {
        authInfo match {
          case Left(authA) =>
            controlA.check(authA).right.map(Left.apply)
          case Right(authB) =>
            controlB.check(authB).right.map(Right.apply)
        }
      }
    }
  }

} 
Example 73
Source File: And.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package org.coursera.naptime.access.combiner

import org.coursera.common.concurrent.Futures
import org.coursera.naptime.NaptimeActionException
import org.coursera.naptime.access.HeaderAccessControl
import play.api.mvc.RequestHeader

import scala.concurrent.ExecutionContext
import scala.concurrent.Future


  def and[A, B, C](
      controlA: HeaderAccessControl[A],
      controlB: HeaderAccessControl[B],
      controlC: HeaderAccessControl[C]): HeaderAccessControl[(A, B, C)] = {

    new HeaderAccessControl[(A, B, C)] {
      override def run(requestHeader: RequestHeader)(
          implicit ec: ExecutionContext): Future[Either[NaptimeActionException, (A, B, C)]] = {

        val futureA = Futures.safelyCall(controlA.run(requestHeader))
        val futureB = Futures.safelyCall(controlB.run(requestHeader))
        val futureC = Futures.safelyCall(controlC.run(requestHeader))

        for {
          resultA <- futureA
          resultB <- futureB
          resultC <- futureC
        } yield {
          (resultA, resultB, resultC) match {
            case (Right(authenticationA), Right(authenticationB), Right(authenticationC)) =>
              Right((authenticationA, authenticationB, authenticationC))
            case _ =>
              List(resultA, resultB).collectFirst { case Left(error) => Left(error) }.head
          }
        }
      }

      override private[naptime] def check(
          authInfo: (A, B, C)): Either[NaptimeActionException, (A, B, C)] = {
        (controlA.check(authInfo._1), controlB.check(authInfo._2), controlC.check(authInfo._3)) match {
          case (Right(a), Right(b), Right(c)) => Right((a, b, c))
          case (Left(err), _, _)              => Left(err)
          case (_, Left(err), _)              => Left(err)
          case (_, _, Left(err))              => Left(err)
        }
      }
    }
  }
} 
Example 74
Source File: SuccessfulOf.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package org.coursera.naptime.access.combiner

import org.coursera.common.concurrent.Futures
import org.coursera.naptime.NaptimeActionException
import org.coursera.naptime.access.HeaderAccessControl
import play.api.http.Status
import play.api.mvc.RequestHeader

import scala.collection.immutable
import scala.concurrent.ExecutionContext
import scala.concurrent.Future


  def successfulOf[A](
      controls: immutable.Seq[HeaderAccessControl[A]]): HeaderAccessControl[Set[A]] = {
    new HeaderAccessControl[Set[A]] {
      override def run(requestHeader: RequestHeader)(
          implicit ec: ExecutionContext): Future[Either[NaptimeActionException, Set[A]]] = {
        Future
          .traverse(controls) { control =>
            Futures.safelyCall(control.run(requestHeader))
          }
          .map { results =>
            val successes = results.collect { case Right(authentication)        => authentication }
            lazy val firstErrorOption = results.collectFirst { case Left(error) => error }
            if (successes.nonEmpty) {
              Right(successes.toSet)
            } else {
              firstErrorOption match {
                case Some(error) => Left(error)
                case None        => badAccessControlsResponse
              }
            }
          }
      }

      override def check(authInfo: Set[A]): Either[NaptimeActionException, Set[A]] = {
        if (authInfo.nonEmpty) Right(authInfo) else badAccessControlsResponse
      }
    }
  }

}

object SuccessfulOf {

  private[combiner] val badAccessControlsResponse = {
    Left(
      NaptimeActionException(
        Status.UNAUTHORIZED,
        Some("auth.perms"),
        Some("Invalid access control configuration")))
  }

} 
Example 75
Source File: HeaderAccessControl.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package org.coursera.naptime.access

import org.coursera.naptime.NaptimeActionException
import org.coursera.naptime.access.authenticator.Authenticator
import org.coursera.naptime.access.authenticator.Decorator
import org.coursera.naptime.access.authenticator.HeaderAuthenticationParser
import org.coursera.naptime.access.authorizer.AuthorizeResult
import org.coursera.naptime.access.authorizer.Authorizer
import org.coursera.naptime.access.combiner.And
import org.coursera.naptime.access.combiner.AnyOf
import org.coursera.naptime.access.combiner.EitherOf
import org.coursera.naptime.access.combiner.SuccessfulOf
import play.api.mvc.RequestHeader

import scala.concurrent.ExecutionContext
import scala.concurrent.Future


  private[naptime] def check(authInfo: A): Either[NaptimeActionException, A]
}

object HeaderAccessControl extends AnyOf with And with EitherOf with SuccessfulOf {

  def allowAll: HeaderAccessControl[Unit] = {
    val parser = HeaderAuthenticationParser.constant(())
    val authorizer = Authorizer[Unit](_ => AuthorizeResult.Authorized)
    StructuredAccessControl(Authenticator(parser, Decorator.identity[Unit]), authorizer)
  }

  import scala.language.implicitConversions
  implicit def accessControlGenerator[BodyType, T](
      accessControl: HeaderAccessControl[T]): (BodyType => HeaderAccessControl[T]) = {
    (b: BodyType) =>
      accessControl
  }

} 
Example 76
Source File: And.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package org.coursera.naptime.access.authenticator.combiner

import org.coursera.naptime.NaptimeActionException
import org.coursera.naptime.access.authenticator.Authenticator
import play.api.mvc.RequestHeader

import scala.concurrent.ExecutionContext
import scala.concurrent.Future

private[authenticator] trait And {

  def and[A, A1, A2](authenticator1: Authenticator[A1], authenticator2: Authenticator[A2])(
      partialCombine: PartialFunction[(Option[A1], Option[A2]), A]): Authenticator[A] = {
    new Authenticator[A] {

      override def maybeAuthenticate(requestHeader: RequestHeader)(
          implicit executionContext: ExecutionContext)
        : Future[Option[Either[NaptimeActionException, A]]] = {

        for {
          response1 <- Authenticator.authenticateAndRecover(authenticator1, requestHeader)
          response2 <- Authenticator.authenticateAndRecover(authenticator2, requestHeader)
        } yield {
          val combine = partialCombine.lift
          (response1, response2) match {
            case (Some(Left(error)), _) => Some(Left(error))
            case (_, Some(Left(error))) => Some(Left(error))
            case _ =>
              val a1Option = response1.flatMap(_.right.toOption)
              val a2Option = response2.flatMap(_.right.toOption)
              combine(a1Option, a2Option).map(Right.apply)
          }
        }
      }
    }
  }

}