generated from ministryofjustice/template-repository
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PI-1568 add cvl user onboarding endpoints
- Loading branch information
1 parent
f153cc3
commit b3f9d5c
Showing
10 changed files
with
184 additions
and
37 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
libs/commons/src/main/kotlin/uk/gov/justice/digital/hmpps/ldap/DeliusRole.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package uk.gov.justice.digital.hmpps.ldap | ||
|
||
interface DeliusRole { | ||
val description: String | ||
val mappedRole: String | ||
val name: String | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,4 +20,22 @@ objectclass: top | |
objectclass: inetOrgPerson | ||
cn: bob-smith | ||
sn: Staff | ||
mail: [email protected] | ||
mail: [email protected] | ||
|
||
dn: cn=ndRoleCatalogue,ou=Users,dc=moj,dc=com | ||
description: Role Catalogue | ||
objectclass: top | ||
cn: ndRoleCatalogue | ||
|
||
dn: cn=LHDCBT002,cn=ndRoleCatalogue,ou=Users,dc=moj,dc=com | ||
description: Digital Licence Create | ||
Level1: TRUE | ||
Level2: FALSE | ||
Level3: FALSE | ||
UIBusinessInteractionCollection: SEBI200 | ||
UIBusinessInteractionCollection: SEBI203 | ||
UIBusinessInteractionCollection: SEBI201 | ||
UIBusinessInteractionCollection: SEBI202 | ||
objectClass: NDRole | ||
objectClass: top | ||
cn: LHDCBT002 |
2 changes: 1 addition & 1 deletion
2
...ary-a-licence-and-delius/src/dev/resources/simulations/__files/hmpps-auth-token-body.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
...delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/UserRoleIntegrationTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package uk.gov.justice.digital.hmpps | ||
|
||
import com.github.tomakehurst.wiremock.WireMockServer | ||
import org.hamcrest.MatcherAssert.assertThat | ||
import org.hamcrest.Matchers.equalTo | ||
import org.junit.jupiter.api.MethodOrderer | ||
import org.junit.jupiter.api.Order | ||
import org.junit.jupiter.api.Test | ||
import org.junit.jupiter.api.TestMethodOrder | ||
import org.junit.jupiter.api.assertThrows | ||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc | ||
import org.springframework.boot.test.context.SpringBootTest | ||
import org.springframework.ldap.NameNotFoundException | ||
import org.springframework.ldap.core.LdapTemplate | ||
import org.springframework.ldap.support.LdapNameBuilder | ||
import org.springframework.test.web.servlet.MockMvc | ||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders | ||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status | ||
import uk.gov.justice.digital.hmpps.api.model.DeliusRole | ||
import uk.gov.justice.digital.hmpps.security.withOAuth2Token | ||
|
||
@AutoConfigureMockMvc | ||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) | ||
@TestMethodOrder(MethodOrderer.OrderAnnotation::class) | ||
internal class UserRoleIntegrationTest { | ||
@Autowired | ||
lateinit var mockMvc: MockMvc | ||
|
||
@Autowired | ||
lateinit var wireMockServer: WireMockServer | ||
|
||
@Autowired | ||
lateinit var ldapTemplate: LdapTemplate | ||
|
||
@Order(1) | ||
@Test | ||
fun `successfully updates ldap role`() { | ||
mockMvc.perform( | ||
MockMvcRequestBuilders.put("/users/john-smith/roles") | ||
.withOAuth2Token(wireMockServer) | ||
).andExpect(status().is2xxSuccessful).andReturn() | ||
|
||
val res = ldapTemplate.lookupContext( | ||
LdapNameBuilder.newInstance("ou=Users") | ||
.add("cn", "john-smith") | ||
.add("cn", DeliusRole.LHDCBT002.name) | ||
.build() | ||
) | ||
assertThat(res.dn.toString(), equalTo("cn=LHDCBT002,cn=john-smith,ou=Users")) | ||
} | ||
|
||
@Order(2) | ||
@Test | ||
fun `successfully removes ldap role`() { | ||
mockMvc.perform( | ||
MockMvcRequestBuilders.delete("/users/john-smith/roles") | ||
.withOAuth2Token(wireMockServer) | ||
).andExpect(status().is2xxSuccessful).andReturn() | ||
|
||
val res = assertThrows<NameNotFoundException> { | ||
ldapTemplate.lookupContext( | ||
LdapNameBuilder.newInstance("ou=Users") | ||
.add("cn", "john-smith") | ||
.add("cn", DeliusRole.LHDCBT002.name) | ||
.build() | ||
) | ||
} | ||
assertThat(res.message, equalTo("[LDAP: error code 32 - Unable to perform the search because base entry 'cn=LHDCBT002,cn=john-smith,ou=Users,dc=moj,dc=com' does not exist in the server.]")) | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
...a-licence-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/DeliusRole.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package uk.gov.justice.digital.hmpps.api.model | ||
|
||
enum class DeliusRole( | ||
override val description: String, | ||
override val mappedRole: String | ||
) : uk.gov.justice.digital.hmpps.ldap.DeliusRole { | ||
LHDCBT002("Digital Licence Create", "CVL_DLC"); | ||
|
||
companion object { | ||
fun from(role: String): DeliusRole? = entries.firstOrNull { it.mappedRole == role.uppercase() } | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
...ence-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/UserResource.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package uk.gov.justice.digital.hmpps.api.resource | ||
|
||
import org.springframework.ldap.core.LdapTemplate | ||
import org.springframework.security.access.prepost.PreAuthorize | ||
import org.springframework.web.bind.annotation.DeleteMapping | ||
import org.springframework.web.bind.annotation.PathVariable | ||
import org.springframework.web.bind.annotation.PutMapping | ||
import org.springframework.web.bind.annotation.RequestMapping | ||
import org.springframework.web.bind.annotation.RestController | ||
import uk.gov.justice.digital.hmpps.api.model.DeliusRole | ||
import uk.gov.justice.digital.hmpps.ldap.addRole | ||
import uk.gov.justice.digital.hmpps.ldap.removeRole | ||
|
||
@RestController | ||
@RequestMapping("users") | ||
class UserResource(private val ldapTemplate: LdapTemplate) { | ||
@PreAuthorize("hasRole('PROBATION_API__CVL__USER_ROLES')") | ||
@PutMapping(value = ["/{username}/roles"]) | ||
fun addRole(@PathVariable username: String) = | ||
ldapTemplate.addRole(username, DeliusRole.LHDCBT002) | ||
|
||
@PreAuthorize("hasRole('PROBATION_API__CVL__USER_ROLES')") | ||
@DeleteMapping(value = ["/{username}/roles"]) | ||
fun removeRole(@PathVariable username: String) = | ||
ldapTemplate.removeRole(username, DeliusRole.LHDCBT002) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 4 additions & 29 deletions
33
...pathfinder-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/UserService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,15 @@ | ||
package uk.gov.justice.digital.hmpps.service | ||
|
||
import org.springframework.ldap.core.LdapTemplate | ||
import org.springframework.ldap.support.LdapNameBuilder | ||
import org.springframework.stereotype.Service | ||
import uk.gov.justice.digital.hmpps.exception.NotFoundException | ||
import uk.gov.justice.digital.hmpps.ldap.addRole | ||
import uk.gov.justice.digital.hmpps.ldap.removeRole | ||
import uk.gov.justice.digital.hmpps.model.DeliusRole | ||
import javax.naming.directory.Attributes | ||
import javax.naming.directory.BasicAttribute | ||
import javax.naming.directory.BasicAttributes | ||
|
||
@Service | ||
class UserService(private val ldapTemplate: LdapTemplate) { | ||
private val ldapBase = "ou=Users" | ||
|
||
fun addRole(username: String, role: DeliusRole) { | ||
val roleContext = ldapTemplate.lookupContext(role.context()) | ||
?: throw NotFoundException("NDeliusRole of ${role.name} not found") | ||
val attributes: Attributes = BasicAttributes(true).apply { | ||
put(roleContext.asAttribute("aliasedObjectName")) | ||
put(role.name.asAttribute("cn")) | ||
put(listOf("NDRoleAssociation", "Alias", "top").asAttribute("objectclass")) | ||
} | ||
val userRole = role.context(username) | ||
ldapTemplate.rebind(userRole, null, attributes) | ||
} | ||
fun addRole(username: String, role: DeliusRole) = ldapTemplate.addRole(username, role) | ||
|
||
fun removeRole(username: String, role: DeliusRole) = | ||
ldapTemplate.unbind(role.context(username)) | ||
|
||
private fun DeliusRole.context(username: String? = null) = | ||
LdapNameBuilder.newInstance(ldapBase) | ||
.add("cn", username ?: "ndRoleCatalogue") | ||
.add("cn", name) | ||
.build() | ||
|
||
fun Any.asAttribute(key: String) = BasicAttribute(key, this.toString()) | ||
fun List<Any>.asAttribute(key: String): BasicAttribute = | ||
BasicAttribute(key).apply { forEach(this::add) } | ||
fun removeRole(username: String, role: DeliusRole) = ldapTemplate.removeRole(username, role) | ||
} |