Skip to content

Commit

Permalink
PI-1495 - make Workforce API consistent with R&M
Browse files Browse the repository at this point in the history
  • Loading branch information
anthony-britton-moj committed Sep 27, 2023
1 parent ce89267 commit 8409819
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,6 @@ interface PersonAccess {
val exclusionMessage: String?
val restrictionMessage: String?
}

fun PersonAccess.isExcluded() = !exclusionMessage.isNullOrBlank()
fun PersonAccess.isRestricted() = !restrictionMessage.isNullOrBlank()
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import uk.gov.justice.digital.hmpps.api.model.UserAccess
import uk.gov.justice.digital.hmpps.api.model.UserDetail
import uk.gov.justice.digital.hmpps.integrations.delius.limitedaccess.entity.PersonAccess
import uk.gov.justice.digital.hmpps.integrations.delius.limitedaccess.entity.UserAccessRepository
import uk.gov.justice.digital.hmpps.integrations.delius.limitedaccess.entity.isExcluded
import uk.gov.justice.digital.hmpps.integrations.delius.limitedaccess.entity.isRestricted
import uk.gov.justice.digital.hmpps.integrations.ldap.entity.LdapUserDetails
import uk.gov.justice.digital.hmpps.ldap.findByUsername

Expand All @@ -29,10 +31,10 @@ class UserService(private val uar: UserAccessRepository, private val ldapTemplat
} else {
CaseAccess(
crn,
any { !it.exclusionMessage.isNullOrBlank() },
any { !it.restrictionMessage.isNullOrBlank() },
firstOrNull { !it.exclusionMessage.isNullOrBlank() }?.exclusionMessage,
firstOrNull { !it.restrictionMessage.isNullOrBlank() }?.restrictionMessage
any { it.isExcluded() },
any { it.isRestricted() },
firstOrNull { it.isExcluded() }?.exclusionMessage,
firstOrNull { it.isRestricted() }?.restrictionMessage
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import uk.gov.justice.digital.hmpps.api.model.CaseAccess
import uk.gov.justice.digital.hmpps.api.model.UserAccess
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.data.generator.UserGenerator
Expand Down Expand Up @@ -47,40 +48,44 @@ class LimitedAccessIntegrationTest {
)
).andReturn().response.contentAsString

val result = objectMapper.readValue<Map<String, UserAccess>>(res)
val result = objectMapper.readValue<UserAccess>(res)
assertThat(
result[PersonGenerator.EXCLUSION.crn],
result.access.first { it.crn == PersonGenerator.EXCLUSION.crn },
equalTo(
UserAccess(
CaseAccess(
PersonGenerator.EXCLUSION.crn,
userExcluded = true,
userRestricted = false,
exclusionMessage = PersonGenerator.EXCLUSION.exclusionMessage
)
)
)
assertThat(
result[PersonGenerator.RESTRICTION.crn],
result.access.first { it.crn == PersonGenerator.RESTRICTION.crn },
equalTo(
UserAccess(
CaseAccess(
PersonGenerator.RESTRICTION.crn,
userExcluded = false,
userRestricted = true,
restrictionMessage = PersonGenerator.RESTRICTION.restrictionMessage
)
)
)
assertThat(
result[PersonGenerator.DEFAULT.crn],
result.access.first { it.crn == PersonGenerator.DEFAULT.crn },
equalTo(
UserAccess(
CaseAccess(
PersonGenerator.DEFAULT.crn,
userExcluded = false,
userRestricted = false
)
)
)
assertThat(
result[PersonGenerator.RESTRICTION_EXCLUSION.crn],
result.access.first { it.crn == PersonGenerator.RESTRICTION_EXCLUSION.crn },
equalTo(
UserAccess(
CaseAccess(
PersonGenerator.RESTRICTION_EXCLUSION.crn,
userExcluded = true,
userRestricted = true,
exclusionMessage = PersonGenerator.RESTRICTION_EXCLUSION.exclusionMessage,
Expand All @@ -107,18 +112,18 @@ class LimitedAccessIntegrationTest {
)
).andReturn().response.contentAsString

val result = objectMapper.readValue<Map<String, UserAccess>>(res)
val result = objectMapper.readValue<UserAccess>(res)
assertThat(
result[PersonGenerator.EXCLUSION.crn],
equalTo(UserAccess.NO_ACCESS_LIMITATIONS)
result.access.first { it.crn == PersonGenerator.EXCLUSION.crn },
equalTo(CaseAccess(PersonGenerator.EXCLUSION.crn, userExcluded = false, userRestricted = false))
)
assertThat(
result[PersonGenerator.RESTRICTION.crn],
equalTo(UserAccess.NO_ACCESS_LIMITATIONS)
result.access.first { it.crn == PersonGenerator.RESTRICTION.crn },
equalTo(CaseAccess(PersonGenerator.RESTRICTION.crn, userExcluded = false, userRestricted = false))
)
assertThat(
result[PersonGenerator.DEFAULT.crn],
equalTo(UserAccess.NO_ACCESS_LIMITATIONS)
result.access.first { it.crn == PersonGenerator.DEFAULT.crn },
equalTo(CaseAccess(PersonGenerator.DEFAULT.crn, userExcluded = false, userRestricted = false))
)
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package uk.gov.justice.digital.hmpps.api.model

data class UserAccess(
data class UserAccess(val access: List<CaseAccess>)

data class CaseAccess(
val crn: String,
val userExcluded: Boolean,
val userRestricted: Boolean,
val exclusionMessage: String? = null,
val restrictionMessage: String? = null
) {
companion object {
val NO_ACCESS_LIMITATIONS = UserAccess(userExcluded = false, userRestricted = false)
}
}
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package uk.gov.justice.digital.hmpps.api.resource

import io.swagger.v3.oas.annotations.Operation
import jakarta.validation.constraints.Size
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestBody
Expand All @@ -27,6 +28,8 @@ class UserResource(private val userAccessService: UserAccessService) {
"""
)
@RequestMapping("/{username}/access-controls", method = [RequestMethod.GET, RequestMethod.POST])
fun userAccessCheck(@PathVariable username: String, @RequestBody crns: List<String>) =
userAccessService.userAccessFor(username, crns)
fun userAccessCheck(
@PathVariable username: String,
@Size(min = 1, max = 500, message = "Please provide between 1 and 500 crns") @RequestBody crns: List<String>
) = userAccessService.userAccessFor(username, crns)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ import uk.gov.justice.digital.hmpps.user.AuditUser
interface UserAccessRepository : JpaRepository<AuditUser, Long> {
@Query(
"""
select new uk.gov.justice.digital.hmpps.integrations.delius.user.access.UserPersonAccess(p.crn, p.exclusionMessage, '')
select p.crn as crn, p.exclusionMessage as exclusionMessage, '' as restrictionMessage
from Person p where p.crn in :crns
and exists (select e from Exclusion e where upper(e.user.username) = upper(:username) and e.person.id = p.id and (e.end is null or e.end > current_date ))
union
select new uk.gov.justice.digital.hmpps.integrations.delius.user.access.UserPersonAccess(p.crn, '', p.restrictionMessage)
select p.crn as crn, '' as exclusionMessage, p.restrictionMessage as restrictionMessage
from Person p where p.crn in :crns
and exists (select r from Restriction r where r.person.id = p.id and (r.end is null or r.end > current_date ))
and not exists (select r from Restriction r where upper(r.user.username) = upper(:username) and r.person.id = p.id and (r.end is null or r.end > current_date ))
"""
)
fun getAccessFor(username: String, crns: List<String>): List<UserPersonAccess>
fun getAccessFor(username: String, crns: List<String>): List<PersonAccess>
}

data class UserPersonAccess(
val crn: String,
val exclusionMessage: String?,
interface PersonAccess {
val crn: String
val exclusionMessage: String?
val restrictionMessage: String?
) {
fun isExcluded(): Boolean = !exclusionMessage.isNullOrBlank()
fun isRestricted(): Boolean = !restrictionMessage.isNullOrBlank()
}

fun PersonAccess.isExcluded() = !exclusionMessage.isNullOrBlank()
fun PersonAccess.isRestricted() = !restrictionMessage.isNullOrBlank()
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
package uk.gov.justice.digital.hmpps.service

import org.springframework.stereotype.Service
import uk.gov.justice.digital.hmpps.api.model.CaseAccess
import uk.gov.justice.digital.hmpps.api.model.UserAccess
import uk.gov.justice.digital.hmpps.integrations.delius.user.access.PersonAccess
import uk.gov.justice.digital.hmpps.integrations.delius.user.access.UserAccessRepository
import uk.gov.justice.digital.hmpps.integrations.delius.user.access.UserPersonAccess
import uk.gov.justice.digital.hmpps.integrations.delius.user.access.isExcluded
import uk.gov.justice.digital.hmpps.integrations.delius.user.access.isRestricted

@Service
class UserAccessService(private val uar: UserAccessRepository) {
fun userAccessFor(username: String, crns: List<String>): Map<String, UserAccess> {
val limitations: Map<String, List<UserPersonAccess>> = uar.getAccessFor(username, crns).groupBy { it.crn }
return crns.associateWith { limitations[it].combined() }
fun userAccessFor(username: String, crns: List<String>): UserAccess {
val limitations: Map<String, List<PersonAccess>> = uar.getAccessFor(username, crns).groupBy { it.crn }
return UserAccess(crns.map { limitations[it].combined(it) })
}

private fun List<UserPersonAccess>?.combined(): UserAccess {
private fun List<PersonAccess>?.combined(crn: String): CaseAccess {
return if (this == null) {
UserAccess.NO_ACCESS_LIMITATIONS
CaseAccess(crn, userExcluded = false, userRestricted = false)
} else {
UserAccess(
CaseAccess(
crn,
any { it.isExcluded() },
any { it.isRestricted() },
firstOrNull { it.isExcluded() }?.exclusionMessage,
Expand Down

0 comments on commit 8409819

Please sign in to comment.