<commit_before>/*
 * Copyright 2016 HM Revenue & Customs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package uk.gov.hmrc.nisp.controllers.auth

import play.api.Logger
import play.api.mvc.{Action, AnyContent, Request, Result}
import uk.gov.hmrc.nisp.auth.{NispCompositePageVisibilityPredicate, GovernmentGatewayProvider, VerifyProvider}
import uk.gov.hmrc.nisp.config.ApplicationConfig
import uk.gov.hmrc.nisp.controllers.routes
import uk.gov.hmrc.nisp.services.{NpsAvailabilityChecker, CitizenDetailsService}
import uk.gov.hmrc.play.frontend.auth._
import uk.gov.hmrc.play.frontend.auth.connectors.domain.Accounts
import uk.gov.hmrc.play.frontend.auth.connectors.domain.ConfidenceLevel.L200
import uk.gov.hmrc.play.frontend.controller.UnauthorisedAction
import uk.gov.hmrc.play.http.HeaderCarrier
import uk.gov.hmrc.play.http.logging.MdcLoggingExecutionContext._

import scala.concurrent.Future

trait AuthorisedForNisp extends Actions {
  val citizenDetailsService: CitizenDetailsService
  val npsAvailabilityChecker: NpsAvailabilityChecker

  private type PlayRequest = Request[AnyContent] => Result
  private type UserRequest = NispUser => PlayRequest
  private type AsyncPlayRequest = Request[AnyContent] => Future[Result]
  private type AsyncUserRequest = NispUser => AsyncPlayRequest

  implicit private def hc(implicit request: Request[_]): HeaderCarrier = HeaderCarrier.fromHeadersAndSession(request.headers, Some(request.session))

  class AuthorisedBy(regime: TaxRegime) {
    val authedBy: AuthenticatedBy = AuthorisedFor(regime, NispCompositePageVisibilityPredicate)
    def async(action: AsyncUserRequest): Action[AnyContent] = {
      if (!npsAvailabilityChecker.isNPSAvailable) {
        UnauthorisedAction(request => Redirect(routes.LandingController.showNpsUnavailable()))
      } else {
        authedBy.async {
          authContext: AuthContext => implicit request =>
            retrieveName(authContext) flatMap { name =>
              action(NispUser(authContext, name))(request)
            }
        }
      }
    }

    def apply(action: UserRequest): Action[AnyContent] = async(user => request => Future.successful(action(user)(request)))
  }

  object AuthorisedByAny extends AuthorisedBy(NispAnyRegime)
  object AuthorisedByVerify extends AuthorisedBy(NispVerifyRegime)

  def retrieveName(authContext: AuthContext)(implicit request: Request[AnyContent]): Future[Option[String]] = {
    val nino = retrieveNino(authContext.principal)
    citizenDetailsService.retrievePerson(nino).map { citizenOption =>
      for (
        citizen <- citizenOption;
        name <- citizen.name;
        firstName <- name.firstName;
        lastName <- name.lastName
      ) yield {
        s"$firstName $lastName"
      }
    }
  }

  private def retrieveNino(principal: Principal): String = {
    principal.accounts.paye match {
      case Some(account) => account.nino.toString()
      case None => Logger.warn("User Paye account is empty"); ""
    }
  }

  trait NispRegime extends TaxRegime {
    override def isAuthorised(accounts: Accounts): Boolean = accounts.paye.isDefined
    override def authenticationType: AuthenticationProvider = new AnyAuthenticationProvider {
      override def ggwAuthenticationProvider: GovernmentGateway = GovernmentGatewayProvider
      override def verifyAuthenticationProvider: Verify = VerifyProvider
      override def login: String = GovernmentGatewayProvider.login
    }
  }

  object NispAnyRegime extends NispRegime
  object NispVerifyRegime extends NispRegime {
    override def authenticationType: AuthenticationProvider = VerifyProvider
  }
}<commit_msg>NISP-1656: Handle session timeout in AnyAuthenticationProvider<commit_after>/*
 * Copyright 2016 HM Revenue & Customs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package uk.gov.hmrc.nisp.controllers.auth

import play.api.Logger
import play.api.mvc.{Action, AnyContent, Request, Result}
import uk.gov.hmrc.nisp.auth.{NispCompositePageVisibilityPredicate, GovernmentGatewayProvider, VerifyProvider}
import uk.gov.hmrc.nisp.config.ApplicationConfig
import uk.gov.hmrc.nisp.controllers.routes
import uk.gov.hmrc.nisp.services.{NpsAvailabilityChecker, CitizenDetailsService}
import uk.gov.hmrc.play.frontend.auth._
import uk.gov.hmrc.play.frontend.auth.connectors.domain.Accounts
import uk.gov.hmrc.play.frontend.auth.connectors.domain.ConfidenceLevel.L200
import uk.gov.hmrc.play.frontend.controller.UnauthorisedAction
import uk.gov.hmrc.play.http.HeaderCarrier
import uk.gov.hmrc.play.http.logging.MdcLoggingExecutionContext._

import scala.concurrent.Future

trait AuthorisedForNisp extends Actions {
  val citizenDetailsService: CitizenDetailsService
  val npsAvailabilityChecker: NpsAvailabilityChecker

  private type PlayRequest = Request[AnyContent] => Result
  private type UserRequest = NispUser => PlayRequest
  private type AsyncPlayRequest = Request[AnyContent] => Future[Result]
  private type AsyncUserRequest = NispUser => AsyncPlayRequest

  implicit private def hc(implicit request: Request[_]): HeaderCarrier = HeaderCarrier.fromHeadersAndSession(request.headers, Some(request.session))

  class AuthorisedBy(regime: TaxRegime) {
    val authedBy: AuthenticatedBy = AuthorisedFor(regime, NispCompositePageVisibilityPredicate)
    def async(action: AsyncUserRequest): Action[AnyContent] = {
      if (!npsAvailabilityChecker.isNPSAvailable) {
        UnauthorisedAction(request => Redirect(routes.LandingController.showNpsUnavailable()))
      } else {
        authedBy.async {
          authContext: AuthContext => implicit request =>
            retrieveName(authContext) flatMap { name =>
              action(NispUser(authContext, name))(request)
            }
        }
      }
    }

    def apply(action: UserRequest): Action[AnyContent] = async(user => request => Future.successful(action(user)(request)))
  }

  object AuthorisedByAny extends AuthorisedBy(NispAnyRegime)
  object AuthorisedByVerify extends AuthorisedBy(NispVerifyRegime)

  def retrieveName(authContext: AuthContext)(implicit request: Request[AnyContent]): Future[Option[String]] = {
    val nino = retrieveNino(authContext.principal)
    citizenDetailsService.retrievePerson(nino).map { citizenOption =>
      for (
        citizen <- citizenOption;
        name <- citizen.name;
        firstName <- name.firstName;
        lastName <- name.lastName
      ) yield {
        s"$firstName $lastName"
      }
    }
  }

  private def retrieveNino(principal: Principal): String = {
    principal.accounts.paye match {
      case Some(account) => account.nino.toString()
      case None => Logger.warn("User Paye account is empty"); ""
    }
  }

  trait NispRegime extends TaxRegime {
    override def isAuthorised(accounts: Accounts): Boolean = accounts.paye.isDefined
    override def authenticationType: AuthenticationProvider = new AnyAuthenticationProvider {
      override def handleSessionTimeout(implicit request: Request[_]): Future[FailureResult] = GovernmentGatewayProvider.handleSessionTimeout
      override def ggwAuthenticationProvider: GovernmentGateway = GovernmentGatewayProvider
      override def verifyAuthenticationProvider: Verify = VerifyProvider
      override def login: String = GovernmentGatewayProvider.login
    }
  }

  object NispAnyRegime extends NispRegime
  object NispVerifyRegime extends NispRegime {
    override def authenticationType: AuthenticationProvider = VerifyProvider
  }
}
{'fraction_non_alphanumeric': 0.08462356695426072, 'fraction_numerical': 0.003072922822361423, 'mean_word_length': 4.362484157160964, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4228658', 'n_tokens_mistral': 2341, 'n_tokens_neox': 2322, 'n_words': 578}