Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2023 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.thirdpartydeveloperfrontend.controllers

import java.time.Clock
import javax.inject.{Inject, Singleton}
import scala.concurrent.ExecutionContext
import scala.concurrent.Future.successful

import views.html._

import play.api.libs.crypto.CookieSigner
import play.api.mvc._

import uk.gov.hmrc.apiplatform.modules.common.domain.models.ApplicationId
import uk.gov.hmrc.apiplatform.modules.common.services.ClockNow
import uk.gov.hmrc.thirdpartydeveloperfrontend.config.{ApplicationConfig, ErrorHandler}
import uk.gov.hmrc.thirdpartydeveloperfrontend.service._

@Singleton
class ManageApplicationController @Inject() (
val errorHandler: ErrorHandler,
val applicationService: ApplicationService,
val applicationActionService: ApplicationActionService,
val sessionService: SessionService,
mcc: MessagesControllerComponents,
val cookieSigner: CookieSigner,
val clock: Clock,
applicationDetailsView: ApplicationDetailsView
)(implicit val ec: ExecutionContext,
val appConfig: ApplicationConfig
) extends ApplicationController(mcc)
with ClockNow {

def applicationDetails(applicationId: ApplicationId): Action[AnyContent] = whenTeamMemberOnApp(applicationId) { implicit request =>
successful(Ok(applicationDetailsView(applicationViewModelFromApplicationRequest(), request.subscriptions)))
}
}
149 changes: 149 additions & 0 deletions app/views/ApplicationDetailsView.scala.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
@*
* Copyright 2023 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.
*@

@import uk.gov.hmrc.govukfrontend.views.html.components._
@import include._
@import uk.gov.hmrc.thirdpartydeveloperfrontend.domain.models.controllers.Crumb
@import uk.gov.hmrc.thirdpartydeveloperfrontend.domain.models.controllers.ApplicationViewModel
@import uk.gov.hmrc.thirdpartydeveloperfrontend.domain.models.apidefinitions.APISubscriptionStatus
@import uk.gov.hmrc.apiplatform.modules.tpd.session.domain.models.UserSession
@import uk.gov.hmrc.thirdpartydeveloperfrontend.controllers.routes
@import uk.gov.hmrc.apiplatform.modules.applications.core.domain.models._
@import uk.gov.hmrc.apiplatform.modules.applications.access.domain.models.Access
@import uk.gov.hmrc.apiplatform.modules.applications.submissions.domain.models.{PrivacyPolicyLocations, TermsAndConditionsLocations}
@import uk.gov.hmrc.thirdpartydeveloperfrontend.domain.models.applications.ApplicationSyntaxes._
@import java.util.Locale
@import java.time.Instant
@import java.time.ZoneId
@import java.time.format.DateTimeFormatter

@this(
devMain: DevMain,
govukTable: GovukTable
)

@(applicationViewModel: ApplicationViewModel, subscriptions: List[APISubscriptionStatus])(
implicit request: play.api.mvc.Request[Any],
loggedIn: UserSession,
messages: Messages,
appConfig: ApplicationConfig,
navSection: String = "details"
)

@formatMaybeDate(maybeDate: Option[Instant], dateFormatter: DateTimeFormatter, defaultString: String) = @{
maybeDate match {
case Some(date) => dateFormatter.format(date)
case _ => defaultString
}
}

@formatRedirectUris(access: Access, defaultString: String) = @{
access match {
case Access.Standard(redirectUris, _, _, _, _, _, _) => formatListOfStrings(redirectUris.toList.map(r => r.toString()), defaultString)
case _ => defaultString
}
}

@formatListOfStrings(values: List[String], defaultString: String) = @{
values.isEmpty match {
case false => values.mkString("<br>")
case true => defaultString
}
}

@app = @{applicationViewModel.application}

@devMain(
title = messages("application.details"),
userFullName = loggedIn.loggedInName,
breadcrumbs = Seq(
Crumb.viewAllApplications,
Crumb.home
),
leftNav = None,
developerSession = Some(loggedIn)
) {

<h1 class="govuk-heading-l">
<span class="govuk-caption-l">@{app.details.name.toString()}</span>
@messages("application.details")
</h1>

@defining(DateTimeFormatter.ofPattern("d MMMM yyyy").withZone(ZoneId.of("Europe/London")).withLocale(Locale.UK)) { dateFormatter =>
@govukTable(Table(
firstCellIsHeader = true,
rows = Seq(
Seq(TableRow(content = Text(messages("application.details.name"))), TableRow(content = Text(app.details.name.toString()), attributes = Map("id" -> "applicationName"))),
Seq(TableRow(content = Text(messages("application.details.environment"))), TableRow(content = Text(app.details.deployedTo.displayText), attributes = Map("id" -> "environment"))),
Seq(TableRow(content = Text(messages("application.details.created"))), TableRow(content = Text(dateFormatter.format(app.details.createdOn)), attributes = Map("id" -> "createdOn"))),
Seq(TableRow(content = Text(messages("application.details.last.api.call"))), TableRow(content = Text(formatMaybeDate(app.details.lastAccess, dateFormatter, "No API called")), attributes = Map("id" -> "lastAccess"))),
Seq(TableRow(content = Text(messages("application.details.description"))), TableRow(content = Text(app.details.description.getOrElse("None")), attributes = Map("id" -> "description")))
)
))
}

<h2 class="govuk-heading-m govuk-!-margin-top-9">@messages("application.details.apis.added")</h2>
<p class="govuk-body">@messages("application.details.apis.hint")</p>

@govukTable(Table(
head = Some(Seq(
HeadCell(content = Text(messages("application.details.api.name")))
)),
rows = subscriptions.filter(sub => sub.subscribed == true).map(subscription => Seq(
TableRow(content = HtmlContent(s"<a href='${appConfig.apiDocumentationFrontendUrl}/api-documentation/docs/api/service/${subscription.serviceName}/${subscription.apiVersion.versionNbr}' class='govuk-link govuk-link--no-visited-state' target='_blank'>${subscription.name} ${subscription.apiVersion.versionNbr.toString()}</a>"))
))
))

<h2 class="govuk-heading-m govuk-!-margin-top-9">@messages("application.details.authorisation.details")</h2>
<p class="govuk-body">@messages("application.details.authorisation.hint")</p>

@govukTable(Table(
firstCellIsHeader = true,
rows = Seq(
Seq(TableRow(content = Text(messages("application.details.client.id"))), TableRow(content = Text(app.details.token.clientId.toString()), attributes = Map("id" -> "clientId"))),
Seq(TableRow(content = Text(messages("application.details.client.secrets"))), TableRow(content = Text(""))),
Seq(TableRow(content = Text(messages("application.details.redirect.uris"))), TableRow(content = HtmlContent(formatRedirectUris(app.details.access, "None added")))),
Seq(TableRow(content = Text(messages("application.details.ip.allow.list"))), TableRow(content = HtmlContent(formatListOfStrings(app.details.ipAllowlist.allowlist.toList, "No IP addresses added"))))
)
))

<h2 class="govuk-heading-m govuk-!-margin-top-9">@messages("application.details.team.members")</h2>
<p class="govuk-body">@messages("application.details.team.hint")</p>

@govukTable(Table(
head = Some(Seq(
HeadCell(content = Text(messages("application.details.team.email"))),
HeadCell(content = Text(messages("application.details.team.role")))
)),
rows = app.collaborators.toList.map(collaborator => Seq(
TableRow(content = Text(collaborator.emailAddress.text)),
TableRow(content = Text(collaborator.role.displayText))
))
))

<h2 class="govuk-heading-m govuk-!-margin-top-9">@messages("application.details.customer.usage")</h2>
<p class="govuk-body">@messages("application.details.customer.hint")</p>

@govukTable(Table(
firstCellIsHeader = true,
rows = Seq(
Seq(TableRow(content = Text(messages("application.details.privacy.policy.url"))), TableRow(content = Text(app.privacyPolicyLocation.getOrElse(PrivacyPolicyLocations.NoneProvided).describe()), attributes = Map("id" -> "privacyPolicy"))),
Seq(TableRow(content = Text(messages("application.details.terms.conditions.url"))), TableRow(content = Text(app.termsAndConditionsLocation.getOrElse(TermsAndConditionsLocations.NoneProvided).describe()), attributes = Map("id" -> "termsAndConditions"))),
Seq(TableRow(content = Text(messages("application.details.grant.length"))), TableRow(content = Text(app.details.grantLength.show()), attributes = Map("id" -> "grantLength")))
)
))

}
2 changes: 1 addition & 1 deletion app/views/DashboardView.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
@(apps: Seq[ApplicationSummary], orgs: Seq[Organisation])(implicit request: play.api.mvc.Request[Any], loggedIn: UserSession, messages: Messages, appConfig: ApplicationConfig)

@buildAppLinkHtml(app: ApplicationSummary) = {
<a href='@controllers.routes.Details.details(app.id)' class='govuk-link govuk-link--no-visited-state'>@{
<a href='@controllers.routes.ManageApplicationController.applicationDetails(app.id)' class='govuk-link govuk-link--no-visited-state'>@{
app.name.toString()
}</a>
}
Expand Down
3 changes: 3 additions & 0 deletions conf/app.routes
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ POST /applications/:id/details/change-terms-conditions-location

GET /applications/:id/details/terms-of-use uk.gov.hmrc.thirdpartydeveloperfrontend.controllers.TermsOfUse.termsOfUse(id: ApplicationId)

GET /applications/:id/manage uk.gov.hmrc.thirdpartydeveloperfrontend.controllers.ManageApplicationController.applicationDetails(id: ApplicationId)


# Used by DOCS Fe
GET /partials/terms-of-use uk.gov.hmrc.thirdpartydeveloperfrontend.controllers.TermsOfUse.termsOfUsePartial()

Expand Down
25 changes: 25 additions & 0 deletions conf/messages
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,28 @@ dashboard.applications.environment=Environment
dashboard.applications.viewall=View all applications
dashboard.applications.create=Create a new application
dashboard.organisations.your=Your organisations

application.details=Application details
application.details.name=Application name
application.details.environment=Environment
application.details.created=Created
application.details.last.api.call=Last API call
application.details.description=Application description
application.details.apis.added=APIs added
application.details.apis.hint=These are the authenticated REST APIs you have added to your application.
application.details.api.name=Name
application.details.authorisation.details=Authorisation details
application.details.authorisation.hint=To use authenticated REST APIs you need to use your client ID and a client secret to authorise your calls.
application.details.client.id=Client ID
application.details.client.secrets=Client secrets
application.details.redirect.uris=Redirect URIs
application.details.ip.allow.list=IP allow list
application.details.team.members=Team members
application.details.team.hint=If other people need to be able to manage this application you can invite them to your team.
application.details.team.email=Email address
application.details.team.role=Role
application.details.customer.usage=Customer usage information
application.details.customer.hint=If you are building software for customers, they need to know how you intend to use their data.
application.details.privacy.policy.url=Privacy policy URL
application.details.terms.conditions.url=Terms and conditions URL
application.details.grant.length=Application grant length
2 changes: 1 addition & 1 deletion project/AppDependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object AppDependencies {
"uk.gov.hmrc" %% "bootstrap-frontend-play-30" % bootstrapVersion,
"uk.gov.hmrc" %% "play-partials-play-30" % "10.2.0",
"uk.gov.hmrc" %% "domain-play-30" % "11.0.0",
"uk.gov.hmrc" %% "play-frontend-hmrc-play-30" % "12.23.0",
"uk.gov.hmrc" %% "play-frontend-hmrc-play-30" % "12.25.0",
"uk.gov.hmrc.mongo" %% "hmrc-mongo-play-30" % mongoVersion,
"uk.gov.hmrc" %% "crypto-json-play-30" % "8.4.0",
"uk.gov.hmrc" %% "http-metrics" % "2.9.0",
Expand Down
Loading