Skip to content

Commit

Permalink
Merge branch 'master' into scala-steward-dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
annielh authored Sep 12, 2024
2 parents 2e3297a + 0133a5f commit 72afa4a
Show file tree
Hide file tree
Showing 69 changed files with 3,333 additions and 2,241 deletions.
39 changes: 21 additions & 18 deletions app/auth/TokenSecurity.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,20 @@ trait TokenSecurity extends OidcSecurity with I18nSupport {
RequestWithToken(request, accessToken)
}

def judgmentTypeAction(consignmentId: UUID)(action: Request[AnyContent] => Future[Result]): Action[AnyContent] = {
consignmentTypeAction(consignmentId, "judgment")(action)
}

def judgmentUserAction(action: Request[AnyContent] => Future[Result]): Action[AnyContent] = secureAction.async { request =>
createResult(action, request, request.token.isJudgmentUser)
}

def judgmentUserAndTypeAction(consignmentId: UUID)(action: Request[AnyContent] => Future[Result]): Action[AnyContent] = {
validatedAction(consignmentId, "judgment", _.isJudgmentUser)(action)
}

def standardUserAction(action: Request[AnyContent] => Future[Result]): Action[AnyContent] = secureAction.async { request =>
createResult(action, request, request.token.isStandardUser)
}

def standardTypeAction(consignmentId: UUID)(action: Request[AnyContent] => Future[Result]): Action[AnyContent] = {
consignmentTypeAction(consignmentId, "standard")(action)
def standardUserAndTypeAction(consignmentId: UUID)(action: Request[AnyContent] => Future[Result]): Action[AnyContent] = {
validatedAction(consignmentId, "standard", _.isStandardUser)(action)
}

def tnaUserAction(action: Request[AnyContent] => Future[Result]): Action[AnyContent] = secureAction.async { request =>
Expand All @@ -76,17 +76,20 @@ trait TokenSecurity extends OidcSecurity with I18nSupport {
}
}

private def consignmentTypeAction(consignmentId: UUID, expectedConsignmentType: String)(action: Request[AnyContent] => Future[Result]): Action[AnyContent] = secureAction.async {
request =>
val token = request.token
consignmentService
.getConsignmentType(consignmentId, token.bearerAccessToken)
.flatMap(consignmentType => {
// These are custom user annotation traces used in Xray
val current = Span.current()
current.setAttribute(consignmentIdKey, consignmentId.toString)
current.setAttribute(userIdKey, token.userId.toString)
createResult(action, request, consignmentType == expectedConsignmentType)
})
private def validatedAction(
consignmentId: UUID,
expectedConsignmentType: String,
isPermitted: Token => Boolean = _ => true
)(action: Request[AnyContent] => Future[Result]): Action[AnyContent] = secureAction.async { request =>
val token = request.token
consignmentService
.getConsignmentType(consignmentId, token.bearerAccessToken)
.flatMap(consignmentType => {
// These are custom user annotation traces used in Xray
val current = Span.current()
current.setAttribute(consignmentIdKey, consignmentId.toString)
current.setAttribute(userIdKey, token.userId.toString)
createResult(action, request, consignmentType == expectedConsignmentType && isPermitted(token))
})
}
}
10 changes: 6 additions & 4 deletions app/controllers/AddAdditionalMetadataController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import org.pac4j.play.scala.SecurityComponents
import play.api.cache._
import play.api.i18n.I18nSupport
import play.api.mvc.{Action, AnyContent, Request, Result}
import services.{ConsignmentService, CustomMetadataService, DisplayPropertiesService}
import services.{ConsignmentService, ConsignmentStatusService, CustomMetadataService, DisplayPropertiesService}
import uk.gov.nationalarchives.tdr.validation.MetadataValidation
import viewsapi.Caching.preventCaching

Expand All @@ -31,28 +31,30 @@ class AddAdditionalMetadataController @Inject() (
val graphqlConfiguration: GraphQLConfiguration,
val keycloakConfiguration: KeycloakConfiguration,
val consignmentService: ConsignmentService,
val consignmentStatusService: ConsignmentStatusService,
val customMetadataService: CustomMetadataService,
val displayPropertiesService: DisplayPropertiesService,
val cache: AsyncCacheApi
)(implicit val ec: ExecutionContext)
extends TokenSecurity
with I18nSupport {

def addAdditionalMetadata(consignmentId: UUID, metadataType: String, fileIds: List[UUID]): Action[AnyContent] = standardTypeAction(consignmentId) {
def addAdditionalMetadata(consignmentId: UUID, metadataType: String, fileIds: List[UUID]): Action[AnyContent] = standardUserAndTypeAction(consignmentId) {
implicit request: Request[AnyContent] =>
for {
consignment <- getConsignmentFileMetadata(consignmentId, metadataType, fileIds)
closureStatusOpen = consignment.files.flatMap(files => files.fileMetadata.find(fmetadata => fmetadata.name == closureType.name && fmetadata.value == "Open")).nonEmpty
consignmentStatuses <- consignmentStatusService.getConsignmentStatuses(consignmentId, request.token.bearerAccessToken)
result <-
if (closureStatusOpen) {
Future(Redirect(routes.AdditionalMetadataClosureStatusController.getClosureStatusPage(consignmentId, metadataType, fileIds)))
} else {
updateFormFields(consignmentId, metadataType, consignment)
}
} yield result
} yield RedirectUtils.redirectIfReviewInProgress(consignmentId, consignmentStatuses)(result)
}

def addAdditionalMetadataSubmit(consignmentId: UUID, metadataType: String, fileIds: List[UUID]): Action[AnyContent] = standardTypeAction(consignmentId) {
def addAdditionalMetadataSubmit(consignmentId: UUID, metadataType: String, fileIds: List[UUID]): Action[AnyContent] = standardUserAndTypeAction(consignmentId) {
implicit request: Request[AnyContent] =>
for {
formFields <- cache.getOrElseUpdate[List[FormField]]("formFields") {
Expand Down
12 changes: 7 additions & 5 deletions app/controllers/AdditionalMetadataClosureStatusController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ package controllers

import auth.TokenSecurity
import configuration.KeycloakConfiguration
import controllers.util.InputNameAndValue
import controllers.util.{InputNameAndValue, RedirectUtils}
import controllers.util.MetadataProperty.{clientSideOriginalFilepath, closureType, fileType}
import graphql.codegen.types.UpdateFileMetadataInput
import org.pac4j.play.scala.SecurityComponents
import play.api.cache.AsyncCacheApi
import play.api.data.Form
import play.api.data.Forms.{boolean, mapping}
import play.api.mvc.{Action, AnyContent, Request, Result}
import services.{ConsignmentService, CustomMetadataService, DisplayPropertiesService}
import services.{ConsignmentService, ConsignmentStatusService, CustomMetadataService, DisplayPropertiesService}

import java.util.UUID
import javax.inject.Inject
Expand All @@ -19,6 +19,7 @@ import scala.concurrent.duration.DurationInt

class AdditionalMetadataClosureStatusController @Inject() (
val consignmentService: ConsignmentService,
val consignmentStatusService: ConsignmentStatusService,
val customMetadataService: CustomMetadataService,
val displayPropertiesService: DisplayPropertiesService,
val keycloakConfiguration: KeycloakConfiguration,
Expand All @@ -37,7 +38,7 @@ class AdditionalMetadataClosureStatusController @Inject() (

private val additionalProperties: List[String] = List(clientSideOriginalFilepath, fileType)

def getClosureStatusPage(consignmentId: UUID, metadataType: String, fileIds: List[UUID]): Action[AnyContent] = standardTypeAction(consignmentId) {
def getClosureStatusPage(consignmentId: UUID, metadataType: String, fileIds: List[UUID]): Action[AnyContent] = standardUserAndTypeAction(consignmentId) {
implicit request: Request[AnyContent] =>
for {
closureProperties <- displayPropertiesService.getDisplayProperties(consignmentId, request.token.bearerAccessToken, Some(metadataType)).map(_.map(_.summary))
Expand All @@ -48,6 +49,7 @@ class AdditionalMetadataClosureStatusController @Inject() (
Some(fileIds),
Some(additionalProperties)
)
consignmentStatuses <- consignmentStatusService.getConsignmentStatuses(consignmentId, request.token.bearerAccessToken)
response <-
if (consignment.files.nonEmpty) {
val filePaths = consignment.files.flatMap(_.fileMetadata).filter(_.name == clientSideOriginalFilepath).map(_.value)
Expand All @@ -72,10 +74,10 @@ class AdditionalMetadataClosureStatusController @Inject() (
} else {
Future.failed(new IllegalStateException(s"Can't find selected files for the consignment $consignmentId"))
}
} yield response
} yield RedirectUtils.redirectIfReviewInProgress(consignmentId, consignmentStatuses)(response)
}

def submitClosureStatus(consignmentId: UUID, metadataType: String, fileIds: List[UUID]): Action[AnyContent] = standardTypeAction(consignmentId) {
def submitClosureStatus(consignmentId: UUID, metadataType: String, fileIds: List[UUID]): Action[AnyContent] = standardUserAndTypeAction(consignmentId) {
implicit request: Request[AnyContent] =>
val errorFunction: Form[ClosureStatusFormData] => Future[Result] = { formWithErrors: Form[ClosureStatusFormData] =>
for {
Expand Down
13 changes: 8 additions & 5 deletions app/controllers/AdditionalMetadataController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ package controllers
import auth.TokenSecurity
import configuration.KeycloakConfiguration
import controllers.AdditionalMetadataController._
import controllers.util.RedirectUtils
import graphql.codegen.GetConsignment.getConsignment.GetConsignment
import graphql.codegen.GetConsignmentFiles
import graphql.codegen.GetConsignmentStatus.getConsignmentStatus.GetConsignment.ConsignmentStatuses
import graphql.codegen.{GetConsignmentFiles, GetConsignmentStatus}
import org.pac4j.play.scala.SecurityComponents
import play.api.Logging
import play.api.mvc.{Action, AnyContent, Request}
import play.api.mvc.Results.Redirect
import play.api.mvc.{Action, AnyContent, Request, Result}
import services.Statuses._
import services.{ConsignmentService, ConsignmentStatusService, DisplayPropertiesService, DisplayProperty}
import uk.gov.nationalarchives.tdr.keycloak.Token
Expand All @@ -26,7 +29,7 @@ class AdditionalMetadataController @Inject() (

val byClosureType: DisplayProperty => Boolean = (dp: DisplayProperty) => dp.propertyType == "Closure"

def start(consignmentId: UUID): Action[AnyContent] = standardTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
def start(consignmentId: UUID): Action[AnyContent] = standardUserAndTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
(for {
consignmentStatuses <- consignmentStatusService.getConsignmentStatuses(consignmentId, request.token.bearerAccessToken)
pageArgs <- getStartPageDetails(consignmentId, request.token)
Expand All @@ -35,7 +38,7 @@ class AdditionalMetadataController @Inject() (
val uploadStatus: Option[String] = statusesToValue.get(UploadType).flatten
uploadStatus match {
case Some(CompletedValue.value) =>
Ok(views.html.standard.additionalMetadataStart(pageArgs))
RedirectUtils.redirectIfReviewInProgress(consignmentId, consignmentStatuses)(Ok(views.html.standard.additionalMetadataStart(pageArgs)))
case Some(InProgressValue.value) | None =>
Redirect(routes.UploadController.uploadPage(consignmentId))
}
Expand Down Expand Up @@ -65,7 +68,7 @@ class AdditionalMetadataController @Inject() (
}
}

def validate(consignmentId: UUID): Action[AnyContent] = standardTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
def validate(consignmentId: UUID): Action[AnyContent] = standardUserAndTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
(for {
pageArgs <- getStartPageDetails(consignmentId, request.token)
statuses <- consignmentService.getConsignmentFilesData(consignmentId, request.token.bearerAccessToken)
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/AdditionalMetadataEntryMethodController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class AdditionalMetadataEntryMethodController @Inject() (
)(AdditionalMetadataEntryData.apply)(AdditionalMetadataEntryData.unapply)
)

def additionalMetadataEntryMethodPage(consignmentId: UUID): Action[AnyContent] = standardTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
def additionalMetadataEntryMethodPage(consignmentId: UUID): Action[AnyContent] = standardUserAndTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
if (applicationConfig.blockDraftMetadataUpload) {
Future(Ok(views.html.notFoundError(name = request.token.name, isLoggedIn = true, isJudgmentUser = false)))
} else {
Expand All @@ -46,7 +46,7 @@ class AdditionalMetadataEntryMethodController @Inject() (
}
}

def submitAdditionalMetadataEntryMethod(consignmentId: UUID): Action[AnyContent] = standardTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
def submitAdditionalMetadataEntryMethod(consignmentId: UUID): Action[AnyContent] = standardUserAndTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
val token = request.token.bearerAccessToken
if (applicationConfig.blockDraftMetadataUpload) {
Future(Ok(views.html.notFoundError(name = request.token.name, isLoggedIn = true, isJudgmentUser = false)))
Expand Down
13 changes: 9 additions & 4 deletions app/controllers/AdditionalMetadataNavigationController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,36 @@ package controllers
import auth.TokenSecurity
import configuration.KeycloakConfiguration
import controllers.util.MetadataProperty.fileType
import controllers.util.RedirectUtils
import org.pac4j.play.scala.SecurityComponents
import play.api.mvc.{Action, AnyContent, Request, Result}
import services.ConsignmentService
import services.{ConsignmentService, ConsignmentStatusService}

import java.util.UUID
import javax.inject.Inject
import scala.concurrent.Future

class AdditionalMetadataNavigationController @Inject() (
val consignmentService: ConsignmentService,
val consignmentStatusService: ConsignmentStatusService,
val keycloakConfiguration: KeycloakConfiguration,
val controllerComponents: SecurityComponents
) extends TokenSecurity {

def getAllFiles(consignmentId: UUID, metadataType: String, expanded: Option[String] = Some("false")): Action[AnyContent] = standardTypeAction(consignmentId) {
def getAllFiles(consignmentId: UUID, metadataType: String, expanded: Option[String] = Some("false")): Action[AnyContent] = standardUserAndTypeAction(consignmentId) {
implicit request: Request[AnyContent] =>
for {
allFiles <- consignmentService.getAllConsignmentFiles(consignmentId, request.token.bearerAccessToken, metadataType)
consignmentStatuses <- consignmentStatusService.getConsignmentStatuses(consignmentId, request.token.bearerAccessToken)
} yield {
val ex = expanded.contains("true")
Ok(views.html.standard.additionalMetadataNavigation(consignmentId, request.token.name, allFiles, metadataType, expanded = ex))
RedirectUtils.redirectIfReviewInProgress(consignmentId, consignmentStatuses)(
Ok(views.html.standard.additionalMetadataNavigation(consignmentId, request.token.name, allFiles, metadataType, expanded = ex))
)
}
}

def submitFiles(consignmentId: UUID, metadataType: String): Action[AnyContent] = standardTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
def submitFiles(consignmentId: UUID, metadataType: String): Action[AnyContent] = standardUserAndTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
val formData = request.body.asFormUrlEncoded
val action = formData.flatMap(_.get("action")).map(_.head)
val fileIds = formData
Expand Down
9 changes: 6 additions & 3 deletions app/controllers/AdditionalMetadataSummaryController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package controllers
import auth.TokenSecurity
import configuration.KeycloakConfiguration
import controllers.util.MetadataProperty.titleAlternate
import controllers.util.RedirectUtils
import graphql.codegen.GetConsignmentFilesMetadata.getConsignmentFilesMetadata.GetConsignment
import graphql.codegen.GetConsignmentFilesMetadata.getConsignmentFilesMetadata.GetConsignment.Files.FileMetadata
import graphql.codegen.types.DataType.{Boolean, DateTime}
import org.pac4j.play.scala.SecurityComponents
import play.api.mvc.{Action, AnyContent, Request}
import services.{ConsignmentService, DisplayPropertiesService, DisplayProperty}
import services.{ConsignmentService, ConsignmentStatusService, DisplayPropertiesService, DisplayProperty}

import java.sql.Timestamp
import java.text.SimpleDateFormat
Expand All @@ -18,15 +19,17 @@ import scala.concurrent.Future

class AdditionalMetadataSummaryController @Inject() (
val consignmentService: ConsignmentService,
val consignmentStatusService: ConsignmentStatusService,
val displayPropertiesService: DisplayPropertiesService,
val keycloakConfiguration: KeycloakConfiguration,
val controllerComponents: SecurityComponents
) extends TokenSecurity {

def getSelectedSummaryPage(consignmentId: UUID, metadataType: String, fileIds: List[UUID], page: Option[String] = None): Action[AnyContent] =
standardTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
standardUserAndTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
for {
consignment <- consignmentService.getConsignmentFileMetadata(consignmentId, request.token.bearerAccessToken, Some(metadataType), Some(fileIds))
consignmentStatuses <- consignmentStatusService.getConsignmentStatuses(consignmentId, request.token.bearerAccessToken)
displayProperties <- displayPropertiesService.getDisplayProperties(consignmentId, request.token.bearerAccessToken, Some(metadataType))
response <- consignment.files match {
case first :: _ =>
Expand Down Expand Up @@ -65,7 +68,7 @@ class AdditionalMetadataSummaryController @Inject() (
}
case Nil => Future.failed(new IllegalStateException(s"Can't find selected files for the consignment $consignmentId"))
}
} yield response
} yield RedirectUtils.redirectIfReviewInProgress(consignmentId, consignmentStatuses)(response)
}

private def getMetadataForView(metadata: List[GetConsignment.Files.FileMetadata], displayProperties: List[DisplayProperty]): List[FileMetadata] = {
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/BeforeUploadingController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class BeforeUploadingController @Inject() (
extends TokenSecurity
with I18nSupport {

def beforeUploading(consignmentId: UUID): Action[AnyContent] = judgmentTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
def beforeUploading(consignmentId: UUID): Action[AnyContent] = judgmentUserAndTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
consignmentService
.getConsignmentRef(consignmentId, request.token.bearerAccessToken)
.map(reference => Ok(views.html.judgment.judgmentBeforeUploading(consignmentId, reference, request.token.name)))
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/ConfirmTransferController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@ class ConfirmTransferController @Inject() (
}
}

def confirmTransfer(consignmentId: UUID): Action[AnyContent] = standardTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
def confirmTransfer(consignmentId: UUID): Action[AnyContent] = standardUserAndTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
loadStandardPageBasedOnCtStatus(consignmentId, Ok)
}

def finalTransferConfirmationSubmit(consignmentId: UUID): Action[AnyContent] =
standardTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
standardUserAndTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
val errorFunction: Form[FinalTransferConfirmationData] => Future[Result] = { formWithErrors: Form[FinalTransferConfirmationData] =>
loadStandardPageBasedOnCtStatus(consignmentId, BadRequest, formWithErrors)
}
Expand Down
Loading

0 comments on commit 72afa4a

Please sign in to comment.