Skip to content

Commit

Permalink
Mibm 168 (#118)
Browse files Browse the repository at this point in the history
* [MIBM-168][PH] obfuscate journey details to enable logging

* [MIBM-168][PH] add some info and warn level logging
  • Loading branch information
PaulHodgson authored Nov 23, 2020
1 parent b247ec9 commit c26906e
Show file tree
Hide file tree
Showing 18 changed files with 301 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package uk.gov.hmrc.merchandiseinbaggage.controllers
import javax.inject.{Inject, Singleton}
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import uk.gov.hmrc.merchandiseinbaggage.config.AppConfig
import uk.gov.hmrc.merchandiseinbaggage.controllers.DeclarationJourneyController.goodsDestinationUnansweredMessage
import uk.gov.hmrc.merchandiseinbaggage.views.html.CannotUseServiceView

@Singleton
Expand All @@ -28,8 +29,9 @@ class CannotUseServiceController @Inject()(override val controllerComponents: Me
extends DeclarationJourneyController {

val onPageLoad: Action[AnyContent] = actionProvider.journeyAction { implicit request =>
request.declarationJourney.maybeGoodsDestination.fold(actionProvider.invalidRequest) { goodsDestination =>
Ok(view(request.declarationJourney.declarationType, goodsDestination))
}
request.declarationJourney.maybeGoodsDestination
.fold(actionProvider.invalidRequest(goodsDestinationUnansweredMessage)) { goodsDestination =>
Ok(view(request.declarationJourney.declarationType, goodsDestination))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import reactivemongo.api.commands.UpdateWriteResult
import uk.gov.hmrc.http.{HeaderCarrier, HttpResponse}
import uk.gov.hmrc.merchandiseinbaggage.config.AppConfig
import uk.gov.hmrc.merchandiseinbaggage.connectors.{MibConnector, PaymentConnector}
import uk.gov.hmrc.merchandiseinbaggage.controllers.DeclarationJourneyController.incompleteMessage
import uk.gov.hmrc.merchandiseinbaggage.forms.CheckYourAnswersForm.form
import uk.gov.hmrc.merchandiseinbaggage.model.api.{Declaration, PayApiRequestBuilder}
import uk.gov.hmrc.merchandiseinbaggage.model.core.DeclarationType.{Export, Import}
Expand All @@ -44,32 +45,26 @@ class CheckYourAnswersController @Inject()(override val controllerComponents: Me
extends DeclarationJourneyUpdateController with PayApiRequestBuilder {

val onPageLoad: Action[AnyContent] = actionProvider.journeyAction.async { implicit request =>
request.declarationJourney.declarationIfRequiredAndComplete.fold(actionProvider.invalidRequestF){ declaration =>
calculationService.paymentCalculation(declaration.declarationGoods).map { paymentCalculations =>
if(declaration.declarationType == Import
&& paymentCalculations.totalGbpValue.value > declaration.goodsDestination.threshold.value) {
Redirect(routes.GoodsOverThresholdController.onPageLoad())
} else {
val taxDue = paymentCalculations.totalTaxDue
Ok(page(form, declaration, taxDue))
request.declarationJourney.declarationIfRequiredAndComplete
.fold(actionProvider.invalidRequestF(incompleteMessage)) { declaration =>
calculationService.paymentCalculation(declaration.declarationGoods).map { paymentCalculations =>
if (declaration.declarationType == Import
&& paymentCalculations.totalGbpValue.value > declaration.goodsDestination.threshold.value) {
Redirect(routes.GoodsOverThresholdController.onPageLoad())
} else Ok(page(form, declaration, paymentCalculations.totalTaxDue))
}
}
}
}

val onSubmit: Action[AnyContent] = actionProvider.journeyAction.async { implicit request =>
request.declarationJourney.declarationIfRequiredAndComplete
.fold(actionProvider.invalidRequestF)(declaration => declarationConfirmation(declaration))
}
.fold(actionProvider.invalidRequestF(incompleteMessage))(declaration => declarationConfirmation(declaration))
}

val addMoreGoods: Action[AnyContent] = actionProvider.journeyAction.async { implicit request =>
val updatedGoodsEntries: Seq[GoodsEntry] = request.declarationJourney.goodsEntries.entries :+ GoodsEntry.empty

repo.upsert(
request.declarationJourney.copy(
goodsEntries = GoodsEntries(updatedGoodsEntries)
)
).map { _ =>
repo.upsert(request.declarationJourney.copy(goodsEntries = GoodsEntries(updatedGoodsEntries))).map { _ =>
Redirect(routes.GoodsTypeQuantityController.onPageLoad(updatedGoodsEntries.size))
}
}
Expand All @@ -85,14 +80,14 @@ class CheckYourAnswersController @Inject()(override val controllerComponents: Me
(implicit request: DeclarationJourneyRequest[AnyContent]): Future[Result] =
for {
persist <- mibConnector.persistDeclaration(declaration)
pay <- createPaymentSession(declaration.declarationGoods)
_ <- resetJourney(persist)
pay <- createPaymentSession(declaration.declarationGoods)
_ <- resetJourney(persist)
} yield Redirect(connector.extractUrl(pay).nextUrl.value)

private def createPaymentSession(goods: DeclarationGoods)(implicit headerCarrier: HeaderCarrier): Future[HttpResponse] =
for {
payApiRequest <- buildRequest(goods, calculationService.paymentCalculation)
response <- connector.createPaymentSession(payApiRequest)
response <- connector.createPaymentSession(payApiRequest)
} yield response

private def resetAndRedirect(declarationId: DeclarationId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import javax.inject.Inject
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import uk.gov.hmrc.merchandiseinbaggage.config.AppConfig
import uk.gov.hmrc.merchandiseinbaggage.connectors.MibConnector
import uk.gov.hmrc.merchandiseinbaggage.controllers.DeclarationJourneyController.incompleteMessage
import uk.gov.hmrc.merchandiseinbaggage.views.html.DeclarationConfirmationView

import scala.concurrent.ExecutionContext
Expand All @@ -33,7 +34,7 @@ class DeclarationConfirmationController @Inject()(
extends DeclarationJourneyController {

val onPageLoad: Action[AnyContent] = actionProvider.journeyAction.async { implicit request =>
request.declarationJourney.declarationId.fold(actionProvider.invalidRequestF) { declarationId =>
request.declarationJourney.declarationId.fold(actionProvider.invalidRequestF(incompleteMessage)) { declarationId =>
connector.findDeclaration(declarationId).map(declaration => Ok(view(declaration)))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import play.api.mvc._
import uk.gov.hmrc.http.SessionKeys
import uk.gov.hmrc.merchandiseinbaggage.model.core.SessionId
import uk.gov.hmrc.merchandiseinbaggage.repositories.DeclarationJourneyRepository
import uk.gov.hmrc.merchandiseinbaggage.utils.DeclarationJourneyLogger

import scala.concurrent.{ExecutionContext, Future}

Expand All @@ -33,21 +34,29 @@ class DeclarationJourneyActionProvider @Inject()(defaultActionBuilder: DefaultAc
def goodsAction(idx: Int): ActionBuilder[DeclarationGoodsRequest, AnyContent] =
defaultActionBuilder andThen journeyActionRefiner andThen goodsActionRefiner(idx)

def invalidRequest: Result = Redirect(routes.InvalidRequestController.onPageLoad())
def invalidRequest(warnMessage: String)(implicit request: RequestHeader): Result = {
DeclarationJourneyLogger.warn(
s"$warnMessage so redirecting to ${routes.InvalidRequestController.onPageLoad()}")(request)
Redirect(routes.InvalidRequestController.onPageLoad())
}

def invalidRequestF: Future[Result] = Future.successful(invalidRequest)
def invalidRequestF(warningMessage: String)(implicit request: RequestHeader): Future[Result] = {
Future.successful(invalidRequest(warningMessage))
}

private def journeyActionRefiner: ActionRefiner[Request, DeclarationJourneyRequest] =
new ActionRefiner[Request, DeclarationJourneyRequest] {

override protected def refine[A](request: Request[A]): Future[Either[Result, DeclarationJourneyRequest[A]]] = {

request.session.get(SessionKeys.sessionId) match {
case None => Future successful Left(invalidRequest)
case None => Future successful Left(invalidRequest("Session Id not found")(request))
case Some(sessionId) =>
repo.findBySessionId(SessionId(sessionId)).map{
case Some(declarationJourney) => Right(new DeclarationJourneyRequest(declarationJourney, request))
case _ => Left(invalidRequest)
repo.findBySessionId(SessionId(sessionId)).map {
case Some(declarationJourney) =>
val declarationJourneyRequest = new DeclarationJourneyRequest(declarationJourney, request)
DeclarationJourneyLogger.info("journeyActionRefiner success")(declarationJourneyRequest)
Right(declarationJourneyRequest)
case _ => Left(invalidRequest("Persisted declaration journey not found")(request))
}
}
}
Expand All @@ -59,10 +68,14 @@ class DeclarationJourneyActionProvider @Inject()(defaultActionBuilder: DefaultAc
new ActionRefiner[DeclarationJourneyRequest, DeclarationGoodsRequest] {

override protected def refine[A](request: DeclarationJourneyRequest[A]): Future[Either[Result, DeclarationGoodsRequest[A]]] = {
request.declarationJourney.goodsEntries.entries.lift(idx - 1) match {
case None => Future successful Left(invalidRequest)
case Some(goodsEntry) => Future successful Right( new DeclarationGoodsRequest(request, goodsEntry))
}
Future successful (request.declarationJourney.goodsEntries.entries.lift(idx - 1) match {
case None =>
Left(invalidRequest(s"Goods entry not found for index $idx")(request))
case Some(goodsEntry) =>
val declarationJourneyRequest = new DeclarationGoodsRequest(request, goodsEntry)
DeclarationJourneyLogger.info("goodsActionRefiner success")(declarationJourneyRequest)
Right(declarationJourneyRequest)
})
}

override protected def executionContext: ExecutionContext = ec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import play.api.i18n.Messages
import play.api.mvc._
import uk.gov.hmrc.merchandiseinbaggage.model.core.{DeclarationJourney, GoodsEntry}
import uk.gov.hmrc.merchandiseinbaggage.repositories.DeclarationJourneyRepository
import uk.gov.hmrc.merchandiseinbaggage.utils.DeclarationJourneyLogger
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController

import scala.concurrent.{ExecutionContext, Future}
Expand All @@ -30,6 +31,12 @@ trait DeclarationJourneyController extends FrontendBaseController {
val onPageLoad: Action[AnyContent]
}

object DeclarationJourneyController {
val incompleteMessage = "declaration journey is not required and complete"
val goodsDestinationUnansweredMessage = "goods destination is unanswered"
val goodsDeclarationIncompleteMessage = "goods declaration is incomplete"
}

trait DeclarationJourneyUpdateController extends DeclarationJourneyController {
val onSubmit: Action[AnyContent]

Expand All @@ -48,10 +55,15 @@ trait IndexedDeclarationJourneyController extends FrontendBaseController {

def onPageLoad(idx: Int): Action[AnyContent]

def withGoodsCategory(goodsEntry: GoodsEntry)(f: String => Future[Result]): Future[Result] =
def withGoodsCategory(goodsEntry: GoodsEntry)
(f: String => Future[Result])
(implicit request: DeclarationGoodsRequest[AnyContent]): Future[Result] =
goodsEntry.maybeCategoryQuantityOfGoods match {
case Some(c) => f(c.category)
case None => Future successful Redirect(routes.InvalidRequestController.onPageLoad())
case None =>
DeclarationJourneyLogger.warn(
s"Goods category not found so redirecting to ${routes.InvalidRequestController.onPageLoad()}")
Future successful Redirect(routes.InvalidRequestController.onPageLoad())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,25 @@ class EoriNumberController @Inject()(

private val backButtonUrl: Call = routes.CustomsAgentController.onPageLoad()

private val invalidRequestMessage = "maybeIsACustomsAgent is unanswered"

val onPageLoad: Action[AnyContent] = actionProvider.journeyAction { implicit request =>
request.declarationJourney.maybeIsACustomsAgent.fold(actionProvider.invalidRequest) { isAgent =>
request.declarationJourney.maybeIsACustomsAgent.fold(actionProvider.invalidRequest(invalidRequestMessage)) { isAgent =>
val preparedForm = request.declarationJourney.maybeEori.fold(form)(e => form.fill(e.value))

Ok(view(preparedForm, isAgent, backButtonUrl))
}
}

val onSubmit: Action[AnyContent] = actionProvider.journeyAction.async { implicit request =>
request.declarationJourney.maybeIsACustomsAgent.fold(actionProvider.invalidRequestF) { isAgent =>
form
.bindFromRequest()
.fold(
formWithErrors =>
Future.successful(BadRequest(view(formWithErrors, isAgent, backButtonUrl))),
eori =>
persistAndRedirect(
request.declarationJourney.copy(maybeEori = Some(Eori(eori))), routes.TravellerDetailsController.onPageLoad())
)
request.declarationJourney.maybeIsACustomsAgent.fold(actionProvider.invalidRequestF(invalidRequestMessage)) { isAgent =>
form.bindFromRequest().fold(
formWithErrors =>
Future.successful(BadRequest(view(formWithErrors, isAgent, backButtonUrl))),
eori =>
persistAndRedirect(
request.declarationJourney.copy(maybeEori = Some(Eori(eori))), routes.TravellerDetailsController.onPageLoad())
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package uk.gov.hmrc.merchandiseinbaggage.controllers
import javax.inject.{Inject, Singleton}
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import uk.gov.hmrc.merchandiseinbaggage.config.AppConfig
import uk.gov.hmrc.merchandiseinbaggage.controllers.DeclarationJourneyController.{goodsDeclarationIncompleteMessage, goodsDestinationUnansweredMessage}
import uk.gov.hmrc.merchandiseinbaggage.service.CalculationService
import uk.gov.hmrc.merchandiseinbaggage.views.html.GoodsOverThresholdView

Expand All @@ -33,13 +34,15 @@ class GoodsOverThresholdController @Inject()(override val controllerComponents:
extends DeclarationJourneyController {

val onPageLoad: Action[AnyContent] = actionProvider.journeyAction.async { implicit request =>
request.declarationJourney.goodsEntries.declarationGoodsIfComplete.fold(actionProvider.invalidRequestF) { goods =>
request.declarationJourney.maybeGoodsDestination.fold(actionProvider.invalidRequestF) { destination =>
for {
paymentCalculations <- calculationService.paymentCalculation(goods)
rates <- calculationService.getConversionRates(goods)
} yield Ok(view(destination, paymentCalculations.totalGbpValue, rates))
request.declarationJourney.goodsEntries.declarationGoodsIfComplete
.fold(actionProvider.invalidRequestF(goodsDeclarationIncompleteMessage)) { goods =>
request.declarationJourney.maybeGoodsDestination
.fold(actionProvider.invalidRequestF(goodsDestinationUnansweredMessage)) { destination =>
for {
paymentCalculations <- calculationService.paymentCalculation(goods)
rates <- calculationService.getConversionRates(goods)
} yield Ok(view(destination, paymentCalculations.totalGbpValue, rates))
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package uk.gov.hmrc.merchandiseinbaggage.controllers
import javax.inject.{Inject, Singleton}
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import uk.gov.hmrc.merchandiseinbaggage.config.AppConfig
import uk.gov.hmrc.merchandiseinbaggage.utils.DeclarationJourneyLogger
import uk.gov.hmrc.merchandiseinbaggage.views.html.InvalidRequestView
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController

Expand All @@ -31,6 +32,7 @@ class InvalidRequestController @Inject()(override val controllerComponents: Mess
extends FrontendBaseController {

def onPageLoad(): Action[AnyContent] = Action { implicit request =>
DeclarationJourneyLogger.warn(s"User was directed to ${routes.InvalidRequestController.onPageLoad()}")
Ok(view())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package uk.gov.hmrc.merchandiseinbaggage.controllers
import javax.inject.{Inject, Singleton}
import play.api.mvc.{Action, AnyContent, Call, MessagesControllerComponents}
import uk.gov.hmrc.merchandiseinbaggage.config.AppConfig
import uk.gov.hmrc.merchandiseinbaggage.controllers.DeclarationJourneyController.{goodsDeclarationIncompleteMessage, goodsDestinationUnansweredMessage}
import uk.gov.hmrc.merchandiseinbaggage.service.CalculationService
import uk.gov.hmrc.merchandiseinbaggage.views.html.PaymentCalculationView

Expand All @@ -35,18 +36,20 @@ class PaymentCalculationController @Inject()(override val controllerComponents:
private val backButtonUrl: Call = routes.ReviewGoodsController.onPageLoad()

val onPageLoad: Action[AnyContent] = actionProvider.journeyAction.async { implicit request =>
request.declarationJourney.goodsEntries.declarationGoodsIfComplete.fold(actionProvider.invalidRequestF) { goods =>
request.declarationJourney.maybeGoodsDestination.fold(actionProvider.invalidRequestF) { destination =>
for {
paymentCalculations <- calculationService.paymentCalculation(goods)
rates <- calculationService.getConversionRates(goods)
} yield {
if(paymentCalculations.totalGbpValue.value > destination.threshold.value)
Redirect(routes.GoodsOverThresholdController.onPageLoad())
else
Ok(view(paymentCalculations, rates, routes.CustomsAgentController.onPageLoad(), backButtonUrl))
}
request.declarationJourney.goodsEntries.declarationGoodsIfComplete
.fold(actionProvider.invalidRequestF(goodsDeclarationIncompleteMessage)) { goods =>
request.declarationJourney.maybeGoodsDestination
.fold(actionProvider.invalidRequestF(goodsDestinationUnansweredMessage)) { destination =>
for {
paymentCalculations <- calculationService.paymentCalculation(goods)
rates <- calculationService.getConversionRates(goods)
} yield {
if (paymentCalculations.totalGbpValue.value > destination.threshold.value)
Redirect(routes.GoodsOverThresholdController.onPageLoad())
else
Ok(view(paymentCalculations, rates, routes.CustomsAgentController.onPageLoad(), backButtonUrl))
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,18 @@ class PurchaseDetailsController @Inject()(
def onSubmit(idx: Int): Action[AnyContent] = actionProvider.goodsAction(idx).async { implicit request: DeclarationGoodsRequest[AnyContent] =>
withGoodsCategory(request.goodsEntry) { category =>
connector.getCurrencies().flatMap { currencyPeriod =>
form
.bindFromRequest()
.fold(
formWithErrors =>
Future.successful(BadRequest(view(formWithErrors, idx, category, currencyPeriod.currencies, backButtonUrl(idx)))),
purchaseDetailsInput =>
currencyPeriod.currencies.find(_.currencyCode == purchaseDetailsInput.currency)
.fold(actionProvider.invalidRequestF) { currency =>
persistAndRedirect(
request.goodsEntry.copy(maybePurchaseDetails = Some(PurchaseDetails(purchaseDetailsInput.price, currency))),
idx,
routes.ReviewGoodsController.onPageLoad())
}
)
form.bindFromRequest().fold(
formWithErrors =>
Future.successful(BadRequest(view(formWithErrors, idx, category, currencyPeriod.currencies, backButtonUrl(idx)))),
purchaseDetailsInput =>
currencyPeriod.currencies.find(_.currencyCode == purchaseDetailsInput.currency)
.fold(actionProvider.invalidRequestF(s"currency [$purchaseDetailsInput.currency] not found")) { currency =>
persistAndRedirect(
request.goodsEntry.copy(maybePurchaseDetails = Some(PurchaseDetails(purchaseDetailsInput.price, currency))),
idx,
routes.ReviewGoodsController.onPageLoad())
}
)
}
}
}
Expand Down
Loading

0 comments on commit c26906e

Please sign in to comment.