From 33217a137555843aa1e6f987c7ddc2b77708a82d Mon Sep 17 00:00:00 2001 From: Topias Heinonen Date: Fri, 25 Aug 2023 10:19:20 +0300 Subject: [PATCH] HAI-1527 Rename role to kayttooikeustaso Role has been used for several different concepts in Haitaton. The used to reference a collection of permission can be renamed to kayttooikeustaso, since that's the word used in the domain. --- ...nkeControllerHankeEditingDisabledITests.kt | 2 +- .../haitaton/hanke/HankeControllerITests.kt | 2 +- .../application/ApplicationServiceITest.kt | 12 +- .../geometria/GeometriatServiceImplITest.kt | 2 +- .../HankeKayttajaControllerITest.kt | 81 ++++++++-- .../permissions/HankeKayttajaServiceITest.kt | 149 +++++++++++------- .../permissions/PermissionServiceITest.kt | 92 +++++++---- .../fi/hel/haitaton/hanke/HankeServiceImpl.kt | 5 +- .../logging/HankeKayttajaLoggingService.kt | 10 +- .../hanke/permissions/HankeKayttaja.kt | 13 +- .../permissions/HankeKayttajaController.kt | 14 +- .../hanke/permissions/HankeKayttajaService.kt | 63 +++++--- .../hanke/permissions/KayttajaTunniste.kt | 11 +- .../{Role.kt => Kayttooikeustaso.kt} | 12 +- .../hanke/permissions/PermissionService.kt | 30 ++-- .../hanke/permissions/PermissionUpdate.kt | 2 +- .../haitaton/hanke/permissions/Permissions.kt | 12 +- .../044-rename-role-to-kayttooikeustaso.yml | 21 +++ .../db/changelog/db.changelog-master.yaml | 2 + .../hanke/factory/HankeKayttajaFactory.kt | 4 +- 20 files changed, 355 insertions(+), 184 deletions(-) rename services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/{Role.kt => Kayttooikeustaso.kt} (65%) create mode 100644 services/hanke-service/src/main/resources/db/changelog/changesets/044-rename-role-to-kayttooikeustaso.yml diff --git a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/HankeControllerHankeEditingDisabledITests.kt b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/HankeControllerHankeEditingDisabledITests.kt index 8cc5e6055..efc421bc2 100644 --- a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/HankeControllerHankeEditingDisabledITests.kt +++ b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/HankeControllerHankeEditingDisabledITests.kt @@ -22,7 +22,7 @@ private const val BASE_URL = "/hankkeet" @WebMvcTest(HankeController::class, properties = ["haitaton.features.hanke-editing=false"]) @Import(IntegrationTestConfiguration::class) @ActiveProfiles("itest") -@WithMockUser(USERNAME, roles = ["haitaton-user"]) +@WithMockUser(USERNAME) class HankeControllerHankeEditingDisabledITests(@Autowired override val mockMvc: MockMvc) : ControllerTest { diff --git a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/HankeControllerITests.kt b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/HankeControllerITests.kt index d736170d6..419f9c780 100644 --- a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/HankeControllerITests.kt +++ b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/HankeControllerITests.kt @@ -50,7 +50,7 @@ private const val BASE_URL = "/hankkeet" @WebMvcTest(HankeController::class) @Import(IntegrationTestConfiguration::class) @ActiveProfiles("itest") -@WithMockUser(USERNAME, roles = ["haitaton-user"]) +@WithMockUser(USERNAME) class HankeControllerITests(@Autowired override val mockMvc: MockMvc) : ControllerTest { @Autowired lateinit var hankeService: HankeService // faking these calls diff --git a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/application/ApplicationServiceITest.kt b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/application/ApplicationServiceITest.kt index d430b3452..77f49dd86 100644 --- a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/application/ApplicationServiceITest.kt +++ b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/application/ApplicationServiceITest.kt @@ -47,8 +47,8 @@ import fi.hel.haitaton.hanke.logging.Operation import fi.hel.haitaton.hanke.logging.Status import fi.hel.haitaton.hanke.logging.UserRole import fi.hel.haitaton.hanke.permissions.KayttajaTunnisteRepository +import fi.hel.haitaton.hanke.permissions.Kayttooikeustaso import fi.hel.haitaton.hanke.permissions.PermissionService -import fi.hel.haitaton.hanke.permissions.Role import fi.hel.haitaton.hanke.permissions.kayttajaTunnistePattern import fi.hel.haitaton.hanke.test.Asserts.isRecent import fi.hel.haitaton.hanke.test.TestUtils @@ -345,8 +345,8 @@ class ApplicationServiceITest : DatabaseTest() { val otherUser = "otherUser" val hanke = hankeRepository.save(HankeEntity(hankeTunnus = "HAI-1234")) val hanke2 = hankeRepository.save(HankeEntity(hankeTunnus = "HAI-1235")) - permissionService.setPermission(hanke.id!!, USERNAME, Role.HAKEMUSASIOINTI) - permissionService.setPermission(hanke2.id!!, "otherUser", Role.HAKEMUSASIOINTI) + permissionService.setPermission(hanke.id!!, USERNAME, Kayttooikeustaso.HAKEMUSASIOINTI) + permissionService.setPermission(hanke2.id!!, "otherUser", Kayttooikeustaso.HAKEMUSASIOINTI) alluDataFactory.saveApplicationEntities(3, USERNAME, hanke = hanke) { _, application -> application.userId = USERNAME @@ -376,8 +376,8 @@ class ApplicationServiceITest : DatabaseTest() { val hanke = hankeRepository.save(HankeEntity(hankeTunnus = "HAI-1234")) val hanke2 = hankeRepository.save(HankeEntity(hankeTunnus = "HAI-1235")) val hanke3 = hankeRepository.save(HankeEntity(hankeTunnus = "HAI-1236")) - permissionService.setPermission(hanke.id!!, USERNAME, Role.HAKEMUSASIOINTI) - permissionService.setPermission(hanke2.id!!, USERNAME, Role.HAKEMUSASIOINTI) + permissionService.setPermission(hanke.id!!, USERNAME, Kayttooikeustaso.HAKEMUSASIOINTI) + permissionService.setPermission(hanke2.id!!, USERNAME, Kayttooikeustaso.HAKEMUSASIOINTI) val application1 = alluDataFactory.saveApplicationEntity(username = USERNAME, hanke = hanke) val application2 = alluDataFactory.saveApplicationEntity(username = "secondUser", hanke = hanke2) @@ -1042,7 +1042,7 @@ class ApplicationServiceITest : DatabaseTest() { val tunnisteet = kayttajaTunnisteRepository.findAll() assertThat(tunnisteet).hasSize(1) - assertThat(tunnisteet[0].role).isEqualTo(Role.KATSELUOIKEUS) + assertThat(tunnisteet[0].kayttooikeustaso).isEqualTo(Kayttooikeustaso.KATSELUOIKEUS) assertThat(tunnisteet[0].createdAt).isRecent() assertThat(tunnisteet[0].sentAt).isNull() assertThat(tunnisteet[0].tunniste).matches(Regex(kayttajaTunnistePattern)) diff --git a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/geometria/GeometriatServiceImplITest.kt b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/geometria/GeometriatServiceImplITest.kt index 90ef83906..ba3fadaf1 100644 --- a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/geometria/GeometriatServiceImplITest.kt +++ b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/geometria/GeometriatServiceImplITest.kt @@ -26,7 +26,7 @@ import org.testcontainers.junit.jupiter.Testcontainers @Testcontainers @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("default") -@WithMockUser(username = "test", roles = ["haitaton-user"]) +@WithMockUser(username = "test") internal class GeometriatServiceImplITest : DatabaseTest() { @Autowired private lateinit var hankeService: HankeService diff --git a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaControllerITest.kt b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaControllerITest.kt index 5475d03ad..45bbccf0e 100644 --- a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaControllerITest.kt +++ b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaControllerITest.kt @@ -151,7 +151,12 @@ class HankeKayttajaControllerITest(@Autowired override val mockMvc: MockMvc) : C ) } throws HankeNotFoundException(HANKE_TUNNUS) - put(url, PermissionUpdate(listOf(PermissionDto(hankeKayttajaId, Role.HANKEMUOKKAUS)))) + put( + url, + PermissionUpdate( + listOf(PermissionDto(hankeKayttajaId, Kayttooikeustaso.HANKEMUOKKAUS)) + ) + ) .andExpect(status().isNotFound) verifySequence { @@ -183,10 +188,15 @@ class HankeKayttajaControllerITest(@Autowired override val mockMvc: MockMvc) : C PermissionCode.MODIFY_DELETE_PERMISSIONS ) } returns false - val updates = mapOf(hankeKayttajaId to Role.HANKEMUOKKAUS) + val updates = mapOf(hankeKayttajaId to Kayttooikeustaso.HANKEMUOKKAUS) justRun { hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) } - put(url, PermissionUpdate(listOf(PermissionDto(hankeKayttajaId, Role.HANKEMUOKKAUS)))) + put( + url, + PermissionUpdate( + listOf(PermissionDto(hankeKayttajaId, Kayttooikeustaso.HANKEMUOKKAUS)) + ) + ) .andExpect(status().isNoContent) .andExpect(content().string("")) @@ -211,10 +221,15 @@ class HankeKayttajaControllerITest(@Autowired override val mockMvc: MockMvc) : C PermissionCode.MODIFY_DELETE_PERMISSIONS ) } returns true - val updates = mapOf(hankeKayttajaId to Role.HANKEMUOKKAUS) + val updates = mapOf(hankeKayttajaId to Kayttooikeustaso.HANKEMUOKKAUS) justRun { hankeKayttajaService.updatePermissions(hanke, updates, true, USERNAME) } - put(url, PermissionUpdate(listOf(PermissionDto(hankeKayttajaId, Role.HANKEMUOKKAUS)))) + put( + url, + PermissionUpdate( + listOf(PermissionDto(hankeKayttajaId, Kayttooikeustaso.HANKEMUOKKAUS)) + ) + ) .andExpect(status().isNoContent) verifyCalls(hanke, updates, deleteAdminPermission = true) @@ -224,7 +239,12 @@ class HankeKayttajaControllerITest(@Autowired override val mockMvc: MockMvc) : C fun `Returns forbidden when missing admin permissions`() { val (hanke, updates) = setupForException(MissingAdminPermissionException(USERNAME)) - put(url, PermissionUpdate(listOf(PermissionDto(hankeKayttajaId, Role.HANKEMUOKKAUS)))) + put( + url, + PermissionUpdate( + listOf(PermissionDto(hankeKayttajaId, Kayttooikeustaso.HANKEMUOKKAUS)) + ) + ) .andExpect(status().isForbidden) .andExpect(hankeError(HankeError.HAI0005)) @@ -235,7 +255,12 @@ class HankeKayttajaControllerITest(@Autowired override val mockMvc: MockMvc) : C fun `Returns forbidden when changing own permissions`() { val (hanke, updates) = setupForException(ChangingOwnPermissionException(USERNAME)) - put(url, PermissionUpdate(listOf(PermissionDto(hankeKayttajaId, Role.HANKEMUOKKAUS)))) + put( + url, + PermissionUpdate( + listOf(PermissionDto(hankeKayttajaId, Kayttooikeustaso.HANKEMUOKKAUS)) + ) + ) .andExpect(status().isForbidden) .andExpect(hankeError(HankeError.HAI4002)) @@ -245,9 +270,16 @@ class HankeKayttajaControllerITest(@Autowired override val mockMvc: MockMvc) : C @Test fun `Returns internal server error if there are users without either permission or tunniste`() { val (hanke, updates) = - setupForException(UsersWithoutRolesException(missingIds = listOf(hankeKayttajaId))) + setupForException( + UsersWithoutKayttooikeustasoException(missingIds = listOf(hankeKayttajaId)) + ) - put(url, PermissionUpdate(listOf(PermissionDto(hankeKayttajaId, Role.HANKEMUOKKAUS)))) + put( + url, + PermissionUpdate( + listOf(PermissionDto(hankeKayttajaId, Kayttooikeustaso.HANKEMUOKKAUS)) + ) + ) .andExpect(status().isInternalServerError) .andExpect(hankeError(HankeError.HAI4003)) @@ -258,7 +290,12 @@ class HankeKayttajaControllerITest(@Autowired override val mockMvc: MockMvc) : C fun `Returns conflict if there would be no admins remaining`() { val (hanke, updates) = setupForException { hanke -> NoAdminRemainingException(hanke) } - put(url, PermissionUpdate(listOf(PermissionDto(hankeKayttajaId, Role.HANKEMUOKKAUS)))) + put( + url, + PermissionUpdate( + listOf(PermissionDto(hankeKayttajaId, Kayttooikeustaso.HANKEMUOKKAUS)) + ) + ) .andExpect(status().isConflict) .andExpect(hankeError(HankeError.HAI4003)) @@ -272,7 +309,12 @@ class HankeKayttajaControllerITest(@Autowired override val mockMvc: MockMvc) : C HankeKayttajatNotFoundException(listOf(hankeKayttajaId), hanke) } - put(url, PermissionUpdate(listOf(PermissionDto(hankeKayttajaId, Role.HANKEMUOKKAUS)))) + put( + url, + PermissionUpdate( + listOf(PermissionDto(hankeKayttajaId, Kayttooikeustaso.HANKEMUOKKAUS)) + ) + ) .andExpect(status().isBadRequest) .andExpect(hankeError(HankeError.HAI4001)) @@ -281,7 +323,7 @@ class HankeKayttajaControllerITest(@Autowired override val mockMvc: MockMvc) : C private fun verifyCalls( hanke: Hanke, - updates: Map, + updates: Map, deleteAdminPermission: Boolean = false, ) { verifySequence { @@ -305,12 +347,14 @@ class HankeKayttajaControllerITest(@Autowired override val mockMvc: MockMvc) : C } } - private fun setupForException(ex: Throwable): Pair> = + private fun setupForException(ex: Throwable): Pair> = setupForException { ex } - private fun setupForException(ex: (Hanke) -> Throwable): Pair> { + private fun setupForException( + ex: (Hanke) -> Throwable + ): Pair> { val hanke = HankeFactory.create() every { hankeService.findHankeOrThrow(HANKE_TUNNUS) } returns hanke justRun { @@ -327,7 +371,7 @@ class HankeKayttajaControllerITest(@Autowired override val mockMvc: MockMvc) : C PermissionCode.MODIFY_DELETE_PERMISSIONS ) } returns false - val updates = mapOf(hankeKayttajaId to Role.HANKEMUOKKAUS) + val updates = mapOf(hankeKayttajaId to Kayttooikeustaso.HANKEMUOKKAUS) every { hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) } throws ex(hanke) @@ -352,7 +396,12 @@ class HankeKayttajaControllerFeatureDisabledITest(@Autowired override val mockMv inner class UpdatePermissions { @Test fun `Returns not found when feature disabled`() { - put(url, PermissionUpdate(listOf(PermissionDto(hankeKayttajaId, Role.HANKEMUOKKAUS)))) + put( + url, + PermissionUpdate( + listOf(PermissionDto(hankeKayttajaId, Kayttooikeustaso.HANKEMUOKKAUS)) + ) + ) .andExpect(status().isNotFound) .andExpect(hankeError(HankeError.HAI0004)) } diff --git a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaServiceITest.kt b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaServiceITest.kt index f0d050f2b..c68bd3f16 100644 --- a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaServiceITest.kt +++ b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaServiceITest.kt @@ -56,7 +56,7 @@ class HankeKayttajaServiceITest : DatabaseTest() { @Autowired private lateinit var kayttajaTunnisteRepository: KayttajaTunnisteRepository @Autowired private lateinit var hankeKayttajaRepository: HankeKayttajaRepository @Autowired private lateinit var permissionRepository: PermissionRepository - @Autowired private lateinit var roleRepository: RoleRepository + @Autowired private lateinit var kayttooikeustasoRepository: KayttooikeustasoRepository @Autowired private lateinit var auditLogRepository: AuditLogRepository @Autowired private lateinit var permissionService: PermissionService @@ -89,7 +89,7 @@ class HankeKayttajaServiceITest : DatabaseTest() { assertThat(id).isEqualTo(entity.id) assertThat(nimi).isEqualTo(entity.nimi) assertThat(sahkoposti).isEqualTo(entity.sahkoposti) - assertThat(rooli).isEqualTo(entity.kayttajaTunniste!!.role) + assertThat(kayttooikeustaso).isEqualTo(entity.kayttajaTunniste!!.kayttooikeustaso) assertThat(tunnistautunut).isEqualTo(false) } } @@ -103,7 +103,8 @@ class HankeKayttajaServiceITest : DatabaseTest() { fun `Saves kayttaja with correct permission and other data`() { val hankeEntity = hankeFactory.saveEntity() val savedHankeId = hankeEntity.id!! - val savedPermission = savePermission(savedHankeId, USERNAME, Role.KAIKKI_OIKEUDET) + val savedPermission = + savePermission(savedHankeId, USERNAME, Kayttooikeustaso.KAIKKI_OIKEUDET) hankeKayttajaService.addHankeFounder(savedHankeId, perustaja, savedPermission) @@ -378,23 +379,23 @@ class HankeKayttajaServiceITest : DatabaseTest() { @Test fun `Doesn't throw any exceptions with no updates`() { val hanke = hankeFactory.save() - val updates = mapOf() + val updates = mapOf() hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) } @Test - fun `Updates role to permission if it exists`() { + fun `Updates kayttooikeustaso to permission if it exists`() { val hanke = hankeFactory.save() val kayttaja = saveUserAndPermission(hanke.id!!) - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) val updatedKayttaja = hankeKayttajaRepository.getReferenceById(kayttaja.id) assertThat(updatedKayttaja.kayttajaTunniste).isNull() assertThat(updatedKayttaja.permission).isNotNull().transform { - it.role.role == Role.HANKEMUOKKAUS + it.kayttooikeustaso.kayttooikeustaso == Kayttooikeustaso.HANKEMUOKKAUS } } @@ -402,7 +403,7 @@ class HankeKayttajaServiceITest : DatabaseTest() { fun `Writes permission update to audit log`() { val hanke = hankeFactory.save() val kayttaja = saveUserAndPermission(hanke.id!!) - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) auditLogRepository.deleteAll() hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) @@ -423,23 +424,25 @@ class HankeKayttajaServiceITest : DatabaseTest() { .isEqualTo(permission.toChangeLogJsonString()) transform { it.target.objectAfter } .isEqualTo( - permission.copy(role = Role.HANKEMUOKKAUS).toChangeLogJsonString() + permission + .copy(kayttooikeustaso = Kayttooikeustaso.HANKEMUOKKAUS) + .toChangeLogJsonString() ) } } @Test - fun `Updates role to tunniste if permission doesn't exist`() { + fun `Updates kayttooikeustaso to tunniste if permission doesn't exist`() { val hanke = hankeFactory.save() val kayttaja = saveUserAndToken(hanke.id!!, "Toinen Tohelo", "urho@kekkonen.test") - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) val updatedKayttaja = hankeKayttajaRepository.getReferenceById(kayttaja.id) assertThat(updatedKayttaja.permission).isNull() assertThat(updatedKayttaja.kayttajaTunniste).isNotNull().transform { - it.role == Role.HANKEMUOKKAUS + it.kayttooikeustaso == Kayttooikeustaso.HANKEMUOKKAUS } } @@ -447,7 +450,7 @@ class HankeKayttajaServiceITest : DatabaseTest() { fun `Writes tunniste update to audit log`() { val hanke = hankeFactory.save() val kayttaja = saveUserAndToken(hanke.id!!, "Toinen Tohelo", "urho@kekkonen.test") - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) auditLogRepository.deleteAll() hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) @@ -467,12 +470,16 @@ class HankeKayttajaServiceITest : DatabaseTest() { kayttaja.kayttajaTunniste!!.toDomain().copy(hankeKayttajaId = kayttaja.id) transform { it.target.objectBefore }.isEqualTo(tunniste.toChangeLogJsonString()) transform { it.target.objectAfter } - .isEqualTo(tunniste.copy(role = Role.HANKEMUOKKAUS).toChangeLogJsonString()) + .isEqualTo( + tunniste + .copy(kayttooikeustaso = Kayttooikeustaso.HANKEMUOKKAUS) + .toChangeLogJsonString() + ) } } @Test - fun `Updates role to only permission if both permission and tunniste exist`() { + fun `Updates kayttooikeustaso to only permission if both permission and tunniste exist`() { val hanke = hankeFactory.save() val tunniste = kayttajaTunnisteRepository.save( @@ -480,7 +487,7 @@ class HankeKayttajaServiceITest : DatabaseTest() { tunniste = "token for both", createdAt = OffsetDateTime.parse("2023-03-31T15:41:21Z"), sentAt = null, - role = Role.KATSELUOIKEUS, + kayttooikeustaso = Kayttooikeustaso.KATSELUOIKEUS, hankeKayttaja = null, ) ) @@ -491,16 +498,16 @@ class HankeKayttajaServiceITest : DatabaseTest() { "kolmas@kehveli.test", kayttajaTunniste = tunniste, ) - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) val updatedKayttaja = hankeKayttajaRepository.getReferenceById(kayttaja.id) assertThat(updatedKayttaja.permission).isNotNull().transform { - it.role.role == Role.HANKEMUOKKAUS + it.kayttooikeustaso.kayttooikeustaso == Kayttooikeustaso.HANKEMUOKKAUS } assertThat(updatedKayttaja.kayttajaTunniste).isNotNull().transform { - it.role == Role.KATSELUOIKEUS + it.kayttooikeustaso == Kayttooikeustaso.KATSELUOIKEUS } } @@ -508,8 +515,12 @@ class HankeKayttajaServiceITest : DatabaseTest() { fun `Throws exception if changing the user's own permission`() { val hanke = hankeFactory.save() val kayttaja = - saveUserAndPermission(hanke.id!!, role = Role.KAIKKIEN_MUOKKAUS, userId = USERNAME) - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + saveUserAndPermission( + hanke.id!!, + kayttooikeustaso = Kayttooikeustaso.KAIKKIEN_MUOKKAUS, + userId = USERNAME + ) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) assertFailure { hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) @@ -524,7 +535,7 @@ class HankeKayttajaServiceITest : DatabaseTest() { fun `Throws exception if given a non-existing Kayttaja Id`() { val missingId = UUID.fromString("b4f4872d-ac5a-43e0-b0bc-79d7d56d238e") val hanke = hankeFactory.save() - val updates = mapOf(missingId to Role.HANKEMUOKKAUS) + val updates = mapOf(missingId to Kayttooikeustaso.HANKEMUOKKAUS) assertFailure { hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) @@ -541,7 +552,7 @@ class HankeKayttajaServiceITest : DatabaseTest() { val hanke1 = hankeFactory.save() val hanke2 = hankeFactory.save() val kayttaja = saveUserAndPermission(hanke2.id!!) - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) assertFailure { hankeKayttajaService.updatePermissions(hanke1, updates, false, USERNAME) @@ -557,13 +568,13 @@ class HankeKayttajaServiceITest : DatabaseTest() { fun `Throws exception if the kayttaja to update has neither permission nor tunniste`() { val hanke = hankeFactory.save() val kayttaja = saveUser(hanke.id!!) - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) assertFailure { hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) } .all { - hasClass(UsersWithoutRolesException::class) + hasClass(UsersWithoutKayttooikeustasoException::class) messageContains(kayttaja.id.toString()) } } @@ -571,8 +582,12 @@ class HankeKayttajaServiceITest : DatabaseTest() { @Test fun `Throws exception without admin permission if the kayttaja to update has KAIKKI_OIKEUDET in permission`() { val hanke = hankeFactory.save() - val kayttaja = saveUserAndPermission(hanke.id!!, role = Role.KAIKKI_OIKEUDET) - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + val kayttaja = + saveUserAndPermission( + hanke.id!!, + kayttooikeustaso = Kayttooikeustaso.KAIKKI_OIKEUDET + ) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) assertFailure { hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) @@ -586,8 +601,9 @@ class HankeKayttajaServiceITest : DatabaseTest() { @Test fun `Throws exception without admin permission if the kayttaja to update has KAIKKI_OIKEUDET in tunniste`() { val hanke = hankeFactory.save() - val kayttaja = saveUserAndToken(hanke.id!!, role = Role.KAIKKI_OIKEUDET) - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + val kayttaja = + saveUserAndToken(hanke.id!!, kayttooikeustaso = Kayttooikeustaso.KAIKKI_OIKEUDET) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) assertFailure { hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) @@ -601,30 +617,35 @@ class HankeKayttajaServiceITest : DatabaseTest() { @Test fun `Succeeds with admin permission when the kayttaja to update has KAIKKI_OIKEUDET in permission`() { val hanke = hankeFactory.save() - val kayttaja = saveUserAndPermission(hanke.id!!, role = Role.KAIKKI_OIKEUDET) - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + val kayttaja = + saveUserAndPermission( + hanke.id!!, + kayttooikeustaso = Kayttooikeustaso.KAIKKI_OIKEUDET + ) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) hankeKayttajaService.updatePermissions(hanke, updates, true, USERNAME) val updatedKayttaja = hankeKayttajaRepository.getReferenceById(kayttaja.id) assertThat(updatedKayttaja.kayttajaTunniste).isNull() assertThat(updatedKayttaja.permission).isNotNull().transform { - it.role.role == Role.HANKEMUOKKAUS + it.kayttooikeustaso.kayttooikeustaso == Kayttooikeustaso.HANKEMUOKKAUS } } @Test fun `Succeeds with with admin permission when the kayttaja to update has KAIKKI_OIKEUDET in tunniste`() { val hanke = hankeFactory.save() - val kayttaja = saveUserAndToken(hanke.id!!, role = Role.KAIKKI_OIKEUDET) - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + val kayttaja = + saveUserAndToken(hanke.id!!, kayttooikeustaso = Kayttooikeustaso.KAIKKI_OIKEUDET) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) hankeKayttajaService.updatePermissions(hanke, updates, true, USERNAME) val updatedKayttaja = hankeKayttajaRepository.getReferenceById(kayttaja.id) assertThat(updatedKayttaja.permission).isNull() assertThat(updatedKayttaja.kayttajaTunniste).isNotNull().transform { - it.role == Role.HANKEMUOKKAUS + it.kayttooikeustaso == Kayttooikeustaso.HANKEMUOKKAUS } } @@ -632,7 +653,7 @@ class HankeKayttajaServiceITest : DatabaseTest() { fun `Throws exception without admin permission if updating to KAIKKI_OIKEUDET`() { val hanke = hankeFactory.save() val kayttaja = saveUserAndToken(hanke.id!!) - val updates = mapOf(kayttaja.id to Role.KAIKKI_OIKEUDET) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.KAIKKI_OIKEUDET) assertFailure { hankeKayttajaService.updatePermissions(hanke, updates, false, USERNAME) @@ -647,14 +668,14 @@ class HankeKayttajaServiceITest : DatabaseTest() { fun `Succeeds with with admin permission if updating to KAIKKI_OIKEUDET`() { val hanke = hankeFactory.save() val kayttaja = saveUserAndToken(hanke.id!!) - val updates = mapOf(kayttaja.id to Role.KAIKKI_OIKEUDET) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.KAIKKI_OIKEUDET) hankeKayttajaService.updatePermissions(hanke, updates, true, USERNAME) val updatedKayttaja = hankeKayttajaRepository.getReferenceById(kayttaja.id) assertThat(updatedKayttaja.permission).isNull() assertThat(updatedKayttaja.kayttajaTunniste).isNotNull().transform { - it.role == Role.HANKEMUOKKAUS + it.kayttooikeustaso == Kayttooikeustaso.HANKEMUOKKAUS } } @@ -662,18 +683,22 @@ class HankeKayttajaServiceITest : DatabaseTest() { fun `Throw exception if trying to demote the last KAIKKI_OIKEUDET kayttaja`() { val hanke = hankeFactory.save() permissionRepository.deleteAll() - val kayttaja = saveUserAndPermission(hanke.id!!, role = Role.KAIKKI_OIKEUDET) + val kayttaja = + saveUserAndPermission( + hanke.id!!, + kayttooikeustaso = Kayttooikeustaso.KAIKKI_OIKEUDET + ) saveUserAndPermission( hanke.id!!, - role = Role.HANKEMUOKKAUS, + kayttooikeustaso = Kayttooikeustaso.HANKEMUOKKAUS, sahkoposti = "hankemuokkaus" ) saveUserAndPermission( hanke.id!!, - role = Role.HAKEMUSASIOINTI, + kayttooikeustaso = Kayttooikeustaso.HAKEMUSASIOINTI, sahkoposti = "hakemusasiointi" ) - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) assertFailure { hankeKayttajaService.updatePermissions(hanke, updates, true, USERNAME) } .all { @@ -685,22 +710,26 @@ class HankeKayttajaServiceITest : DatabaseTest() { @Test fun `Don't throw an exception if an anonymous user still has KAIKKI_OIKEUDET`() { val hanke = hankeFactory.save() - permissionService.setPermission(hanke.id!!, USERNAME, Role.KAIKKI_OIKEUDET) - val kayttaja = saveUserAndPermission(hanke.id!!, role = Role.KAIKKI_OIKEUDET) - val updates = mapOf(kayttaja.id to Role.HANKEMUOKKAUS) + permissionService.setPermission(hanke.id!!, USERNAME, Kayttooikeustaso.KAIKKI_OIKEUDET) + val kayttaja = + saveUserAndPermission( + hanke.id!!, + kayttooikeustaso = Kayttooikeustaso.KAIKKI_OIKEUDET + ) + val updates = mapOf(kayttaja.id to Kayttooikeustaso.HANKEMUOKKAUS) hankeKayttajaService.updatePermissions(hanke, updates, true, USERNAME) val updatedKayttaja = hankeKayttajaRepository.getReferenceById(kayttaja.id) assertThat(updatedKayttaja.permission).isNotNull().transform { - it.role.role == Role.HANKEMUOKKAUS + it.kayttooikeustaso.kayttooikeustaso == Kayttooikeustaso.HANKEMUOKKAUS } } } private fun Assert>.areValid() = each { t -> t.transform { it.id }.isNotNull() - t.transform { it.role }.isEqualTo(Role.KATSELUOIKEUS) + t.transform { it.kayttooikeustaso }.isEqualTo(Kayttooikeustaso.KATSELUOIKEUS) t.transform { it.createdAt }.isRecent() t.transform { it.sentAt }.isNull() t.transform { it.tunniste }.matches(Regex(kayttajaTunnistePattern)) @@ -721,14 +750,15 @@ class HankeKayttajaServiceITest : DatabaseTest() { assertThat(actual.id).isEqualTo(other.id) assertThat(actual.hankeId).isEqualTo(other.hankeId) assertThat(actual.userId).isEqualTo(other.userId) - assertThat(actual.role).isOfEqualDataTo(other.role) + assertThat(actual.kayttooikeustaso).isOfEqualDataTo(other.kayttooikeustaso) } - private fun Assert.isOfEqualDataTo(other: RoleEntity) = given { actual -> - assertThat(actual.id).isEqualTo(other.id) - assertThat(actual.role).isEqualTo(other.role) - assertThat(actual.permissionCode).isEqualTo(other.permissionCode) - } + private fun Assert.isOfEqualDataTo(other: KayttooikeustasoEntity) = + given { actual -> + assertThat(actual.id).isEqualTo(other.id) + assertThat(actual.kayttooikeustaso).isEqualTo(other.kayttooikeustaso) + assertThat(actual.permissionCode).isEqualTo(other.permissionCode) + } private val expectedNames = arrayOf( @@ -750,7 +780,7 @@ class HankeKayttajaServiceITest : DatabaseTest() { hankeId: Int, nimi: String = "Kake Katselija", sahkoposti: String = "kake@katselu.test", - role: Role = Role.KATSELUOIKEUS, + kayttooikeustaso: Kayttooikeustaso = Kayttooikeustaso.KATSELUOIKEUS, tunniste: String = "existing", ): HankeKayttajaEntity { val kayttajaTunnisteEntity = @@ -759,7 +789,7 @@ class HankeKayttajaServiceITest : DatabaseTest() { tunniste = tunniste, createdAt = OffsetDateTime.parse("2023-03-31T15:41:21Z"), sentAt = null, - role = role, + kayttooikeustaso = kayttooikeustaso, hankeKayttaja = null, ) ) @@ -770,11 +800,11 @@ class HankeKayttajaServiceITest : DatabaseTest() { hankeId: Int, nimi: String = "Kake Katselija", sahkoposti: String = "kake@katselu.test", - role: Role = Role.KATSELUOIKEUS, + kayttooikeustaso: Kayttooikeustaso = Kayttooikeustaso.KATSELUOIKEUS, userId: String = "fake id", kayttajaTunniste: KayttajaTunnisteEntity? = null, ): HankeKayttajaEntity { - val permissionEntity = savePermission(hankeId, userId, role) + val permissionEntity = savePermission(hankeId, userId, kayttooikeustaso) return saveUser(hankeId, nimi, sahkoposti, permissionEntity, kayttajaTunniste) } @@ -797,12 +827,13 @@ class HankeKayttajaServiceITest : DatabaseTest() { ) } - private fun savePermission(hankeId: Int, userId: String, role: Role) = + private fun savePermission(hankeId: Int, userId: String, kayttooikeustaso: Kayttooikeustaso) = permissionRepository.save( PermissionEntity( userId = userId, hankeId = hankeId, - role = roleRepository.findOneByRole(role) + kayttooikeustaso = + kayttooikeustasoRepository.findOneByKayttooikeustaso(kayttooikeustaso) ) ) } diff --git a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/permissions/PermissionServiceITest.kt b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/permissions/PermissionServiceITest.kt index e5070ff5e..1a1490812 100644 --- a/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/permissions/PermissionServiceITest.kt +++ b/services/hanke-service/src/integrationTest/kotlin/fi/hel/haitaton/hanke/permissions/PermissionServiceITest.kt @@ -30,16 +30,16 @@ class PermissionServiceITest : DatabaseTest() { @Autowired lateinit var permissionService: PermissionService @Autowired lateinit var permissionRepository: PermissionRepository - @Autowired lateinit var roleRepository: RoleRepository + @Autowired lateinit var kayttooikeustasoRepository: KayttooikeustasoRepository @Autowired lateinit var hankeService: HankeService companion object { @JvmStatic - fun roleArguments() = + fun kayttooikeustasot() = listOf( - Arguments.of(Role.KAIKKI_OIKEUDET, PermissionCode.values()), + Arguments.of(Kayttooikeustaso.KAIKKI_OIKEUDET, PermissionCode.values()), Arguments.of( - Role.KAIKKIEN_MUOKKAUS, + Kayttooikeustaso.KAIKKIEN_MUOKKAUS, arrayOf( PermissionCode.VIEW, PermissionCode.MODIFY_VIEW_PERMISSIONS, @@ -50,36 +50,42 @@ class PermissionServiceITest : DatabaseTest() { ) ), Arguments.of( - Role.HANKEMUOKKAUS, + Kayttooikeustaso.HANKEMUOKKAUS, arrayOf( PermissionCode.VIEW, PermissionCode.EDIT, ) ), Arguments.of( - Role.HAKEMUSASIOINTI, + Kayttooikeustaso.HAKEMUSASIOINTI, arrayOf( PermissionCode.VIEW, PermissionCode.EDIT_APPLICATIONS, ) ), - Arguments.of(Role.KATSELUOIKEUS, arrayOf(PermissionCode.VIEW)), + Arguments.of(Kayttooikeustaso.KATSELUOIKEUS, arrayOf(PermissionCode.VIEW)), ) } @ParameterizedTest - @MethodSource("roleArguments") - fun `roles have correct permissions`(role: Role, allowedPermissions: Array) { - val roleEntity = roleRepository.findOneByRole(role) + @MethodSource("kayttooikeustasot") + fun `All kayttooikeustaso have correct permissions`( + kayttooikeustaso: Kayttooikeustaso, + allowedPermissions: Array + ) { + val kayttooikeustasoEntity = + kayttooikeustasoRepository.findOneByKayttooikeustaso(kayttooikeustaso) allowedPermissions.forEach { code -> - assertThat(code).transform { PermissionService.hasPermission(roleEntity, it) }.isTrue() + assertThat(code) + .transform { PermissionService.hasPermission(kayttooikeustasoEntity, it) } + .isTrue() } PermissionCode.values() .filter { !allowedPermissions.contains(it) } .forEach { code -> assertThat(code) - .transform { PermissionService.hasPermission(roleEntity, it) } + .transform { PermissionService.hasPermission(kayttooikeustasoEntity, it) } .isFalse() } } @@ -93,7 +99,8 @@ class PermissionServiceITest : DatabaseTest() { @Test fun `getAllowedHankeIds with permissions returns list of IDs`() { - val kaikkiOikeudet = roleRepository.findOneByRole(Role.KAIKKI_OIKEUDET) + val kaikkiOikeudet = + kayttooikeustasoRepository.findOneByKayttooikeustaso(Kayttooikeustaso.KAIKKI_OIKEUDET) val hankkeet = saveSeveralHanke(3) hankkeet .map { it.id!! } @@ -102,7 +109,7 @@ class PermissionServiceITest : DatabaseTest() { PermissionEntity( userId = username, hankeId = it, - role = kaikkiOikeudet, + kayttooikeustaso = kaikkiOikeudet, ) ) } @@ -114,19 +121,23 @@ class PermissionServiceITest : DatabaseTest() { @Test fun `getAllowedHankeIds return ids with correct permissions`() { - val kaikkiOikeudet = roleRepository.findOneByRole(Role.KAIKKI_OIKEUDET) - val hankemuokkaus = roleRepository.findOneByRole(Role.HANKEMUOKKAUS) - val hakemusasiointi = roleRepository.findOneByRole(Role.HAKEMUSASIOINTI) - val katseluoikeus = roleRepository.findOneByRole(Role.KATSELUOIKEUS) + val kaikkiOikeudet = + kayttooikeustasoRepository.findOneByKayttooikeustaso(Kayttooikeustaso.KAIKKI_OIKEUDET) + val hankemuokkaus = + kayttooikeustasoRepository.findOneByKayttooikeustaso(Kayttooikeustaso.HANKEMUOKKAUS) + val hakemusasiointi = + kayttooikeustasoRepository.findOneByKayttooikeustaso(Kayttooikeustaso.HAKEMUSASIOINTI) + val katseluoikeus = + kayttooikeustasoRepository.findOneByKayttooikeustaso(Kayttooikeustaso.KATSELUOIKEUS) val hankkeet = saveSeveralHanke(4) listOf(kaikkiOikeudet, hankemuokkaus, hakemusasiointi, katseluoikeus).zip(hankkeet) { - role, + kayttooikeustaso, hanke -> permissionRepository.save( PermissionEntity( userId = username, hankeId = hanke.id!!, - role = role, + kayttooikeustaso = kayttooikeustaso, ) ) } @@ -143,10 +154,15 @@ class PermissionServiceITest : DatabaseTest() { @Test fun `hasPermission with correct permission`() { - val kaikkiOikeudet = roleRepository.findOneByRole(Role.KAIKKI_OIKEUDET) + val kaikkiOikeudet = + kayttooikeustasoRepository.findOneByKayttooikeustaso(Kayttooikeustaso.KAIKKI_OIKEUDET) val hankeId = saveSeveralHanke(1)[0].id!! permissionRepository.save( - PermissionEntity(userId = username, hankeId = hankeId, role = kaikkiOikeudet) + PermissionEntity( + userId = username, + hankeId = hankeId, + kayttooikeustaso = kaikkiOikeudet + ) ) assertTrue(permissionService.hasPermission(hankeId, username, PermissionCode.EDIT)) @@ -154,10 +170,15 @@ class PermissionServiceITest : DatabaseTest() { @Test fun `hasPermission with insufficient permissions`() { - val hakemusasiointi = roleRepository.findOneByRole(Role.HAKEMUSASIOINTI) + val hakemusasiointi = + kayttooikeustasoRepository.findOneByKayttooikeustaso(Kayttooikeustaso.HAKEMUSASIOINTI) val hankeId = saveSeveralHanke(1)[0].id!! permissionRepository.save( - PermissionEntity(userId = username, hankeId = hankeId, role = hakemusasiointi) + PermissionEntity( + userId = username, + hankeId = hankeId, + kayttooikeustaso = hakemusasiointi + ) ) assertFalse(permissionService.hasPermission(hankeId, username, PermissionCode.EDIT)) @@ -168,29 +189,40 @@ class PermissionServiceITest : DatabaseTest() { val hankeId = saveSeveralHanke(1)[0].id!! permissionRepository.deleteAll() // remove permission created in hanke creation - permissionService.setPermission(hankeId, username, Role.KATSELUOIKEUS) + permissionService.setPermission(hankeId, username, Kayttooikeustaso.KATSELUOIKEUS) val permissions = permissionRepository.findAll() assertThat(permissions).hasSize(1) assertEquals(hankeId, permissions[0].hankeId) - assertEquals(Role.KATSELUOIKEUS, permissions[0].role.role) + assertEquals( + Kayttooikeustaso.KATSELUOIKEUS, + permissions[0].kayttooikeustaso.kayttooikeustaso + ) } @Test fun `setPermission updates an existing permission`() { val hankeId = saveSeveralHanke(1)[0].id!! permissionRepository.deleteAll() // remove permission created in hanke creation - val role = roleRepository.findOneByRole(Role.KATSELUOIKEUS) + val kayttooikeustaso = + kayttooikeustasoRepository.findOneByKayttooikeustaso(Kayttooikeustaso.KATSELUOIKEUS) permissionRepository.save( - PermissionEntity(userId = username, hankeId = hankeId, role = role) + PermissionEntity( + userId = username, + hankeId = hankeId, + kayttooikeustaso = kayttooikeustaso + ) ) - permissionService.setPermission(hankeId, username, Role.HAKEMUSASIOINTI) + permissionService.setPermission(hankeId, username, Kayttooikeustaso.HAKEMUSASIOINTI) val permissions = permissionRepository.findAll() assertThat(permissions).hasSize(1) assertEquals(hankeId, permissions[0].hankeId) - assertEquals(Role.HAKEMUSASIOINTI, permissions[0].role.role) + assertEquals( + Kayttooikeustaso.HAKEMUSASIOINTI, + permissions[0].kayttooikeustaso.kayttooikeustaso + ) } private fun saveSeveralHanke(n: Int) = diff --git a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/HankeServiceImpl.kt b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/HankeServiceImpl.kt index 0304d2208..a31473e71 100644 --- a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/HankeServiceImpl.kt +++ b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/HankeServiceImpl.kt @@ -21,8 +21,8 @@ import fi.hel.haitaton.hanke.logging.HankeLoggingService import fi.hel.haitaton.hanke.logging.Operation import fi.hel.haitaton.hanke.logging.YhteystietoLoggingEntryHolder import fi.hel.haitaton.hanke.permissions.HankeKayttajaService +import fi.hel.haitaton.hanke.permissions.Kayttooikeustaso import fi.hel.haitaton.hanke.permissions.PermissionService -import fi.hel.haitaton.hanke.permissions.Role import fi.hel.haitaton.hanke.tormaystarkastelu.TormaystarkasteluLaskentaService import fi.hel.haitaton.hanke.tormaystarkastelu.TormaystarkasteluTulos import fi.hel.haitaton.hanke.tormaystarkastelu.TormaystarkasteluTulosEntity @@ -246,7 +246,8 @@ open class HankeServiceImpl( private fun initAccessForCreatedHanke(hanke: Hanke, perustaja: Perustaja?, userId: String) { val hankeId = hanke.id!! - val permissionAll = permissionService.setPermission(hankeId, userId, Role.KAIKKI_OIKEUDET) + val permissionAll = + permissionService.setPermission(hankeId, userId, Kayttooikeustaso.KAIKKI_OIKEUDET) perustaja?.let { hankeKayttajaService.addHankeFounder(hankeId, it, permissionAll) } hankeKayttajaService.saveNewTokensFromHanke(hanke) } diff --git a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/logging/HankeKayttajaLoggingService.kt b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/logging/HankeKayttajaLoggingService.kt index e04c33a9c..9b1e701ac 100644 --- a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/logging/HankeKayttajaLoggingService.kt +++ b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/logging/HankeKayttajaLoggingService.kt @@ -2,8 +2,8 @@ package fi.hel.haitaton.hanke.logging import fi.hel.haitaton.hanke.application.Application import fi.hel.haitaton.hanke.permissions.KayttajaTunniste +import fi.hel.haitaton.hanke.permissions.Kayttooikeustaso import fi.hel.haitaton.hanke.permissions.PermissionEntity -import fi.hel.haitaton.hanke.permissions.Role import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Propagation import org.springframework.transaction.annotation.Transactional @@ -19,9 +19,13 @@ class HankeKayttajaLoggingService(private val auditLogService: AuditLogService) } @Transactional(propagation = Propagation.MANDATORY) - fun logUpdate(roleBefore: Role, permissionEntityAfter: PermissionEntity, userId: String) { + fun logUpdate( + kayttooikeustasoBefore: Kayttooikeustaso, + permissionEntityAfter: PermissionEntity, + userId: String + ) { val permissionAfter = permissionEntityAfter.toDomain() - val permissionBefore = permissionAfter.copy(role = roleBefore) + val permissionBefore = permissionAfter.copy(kayttooikeustaso = kayttooikeustasoBefore) AuditLogService.updateEntry( userId, diff --git a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttaja.kt b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttaja.kt index b3b663c54..3516f8112 100644 --- a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttaja.kt +++ b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttaja.kt @@ -21,7 +21,7 @@ data class HankeKayttajaDto( @field:Schema(description = "Id, set by the service") val id: UUID, @field:Schema(description = "Email address") val sahkoposti: String, @field:Schema(description = "Full name") val nimi: String, - @field:Schema(description = "Role in Hanke") val rooli: Role?, + @field:Schema(description = "Access level in Hanke") val kayttooikeustaso: Kayttooikeustaso?, @field:Schema(description = "Has user logged in to view Hanke") val tunnistautunut: Boolean, ) @@ -44,17 +44,18 @@ class HankeKayttajaEntity( id = id, sahkoposti = sahkoposti, nimi = nimi, - rooli = deriveRole(), + kayttooikeustaso = deriveKayttooikeustaso(), tunnistautunut = permission != null, ) /** - * [KayttajaTunnisteEntity] stores role temporarily until user has signed in. After that, - * [PermissionEntity] is used. + * [KayttajaTunnisteEntity] stores kayttooikeustaso temporarily until user has signed in. After + * that, [PermissionEntity] is used. * - * Thus, role is read primarily from [PermissionEntity] if the relation exists. + * Thus, kayttooikeustaso is read primarily from [PermissionEntity] if the relation exists. */ - fun deriveRole(): Role? = permission?.role?.role ?: kayttajaTunniste?.role + fun deriveKayttooikeustaso(): Kayttooikeustaso? = + permission?.kayttooikeustaso?.kayttooikeustaso ?: kayttajaTunniste?.kayttooikeustaso } @Repository diff --git a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaController.kt b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaController.kt index bca35c1fe..97261aa28 100644 --- a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaController.kt +++ b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaController.kt @@ -95,14 +95,14 @@ permissions are updated to the user tokens, i.e. this call will change which permissions the user will get when they activate their permissions. The reply from the list users endpoint can be modified and used here, but -only the ID and role fields are read. +only the ID and kayttooikeustaso fields are read. Only the IDs that are mentioned are updated, so only updated IDs need to be listed. This also means that this endpoint can't be used to remove permissions. -If removing or adding KAIKKI_OIKEUDET role, the caller needs to have those -same permissions. +If removing or adding KAIKKI_OIKEUDET kayttooikeustaso, the caller needs to +have those same permissions. """ ) @ApiResponses( @@ -158,7 +158,7 @@ same permissions. hankeKayttajaService.updatePermissions( hanke, - permissions.kayttajat.associate { it.id to it.rooli }, + permissions.kayttajat.associate { it.id to it.kayttooikeustaso }, deleteAdminPermission, userId ) @@ -180,10 +180,12 @@ same permissions. return HankeError.HAI4002 } - @ExceptionHandler(UsersWithoutRolesException::class) + @ExceptionHandler(UsersWithoutKayttooikeustasoException::class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @Hidden - fun usersWithoutRolesException(ex: UsersWithoutRolesException): HankeError { + fun usersWithoutKayttooikeustasoException( + ex: UsersWithoutKayttooikeustasoException + ): HankeError { logger.error(ex) { ex.message } return HankeError.HAI4003 } diff --git a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaService.kt b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaService.kt index 3f09ac23e..d31924f4f 100644 --- a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaService.kt +++ b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/HankeKayttajaService.kt @@ -18,7 +18,7 @@ private val logger = KotlinLogging.logger {} class HankeKayttajaService( private val hankeKayttajaRepository: HankeKayttajaRepository, private val kayttajaTunnisteRepository: KayttajaTunnisteRepository, - private val roleRepository: RoleRepository, + private val kayttooikeustasoRepository: KayttooikeustasoRepository, private val permissionService: PermissionService, private val featureFlags: FeatureFlags, private val logService: HankeKayttajaLoggingService, @@ -83,7 +83,7 @@ class HankeKayttajaService( @Transactional fun updatePermissions( hanke: Hanke, - updates: Map, + updates: Map, deleteAdminPermission: Boolean, userId: String, ) { @@ -102,12 +102,13 @@ class HankeKayttajaService( kayttajat.forEach { kayttaja -> if (kayttaja.permission != null) { - val roleBefore = kayttaja.permission.role.role - kayttaja.permission.role = roleRepository.findOneByRole(updates[kayttaja.id]!!) - logService.logUpdate(roleBefore, kayttaja.permission, userId) + val kayttooikeustasoBefore = kayttaja.permission.kayttooikeustaso.kayttooikeustaso + kayttaja.permission.kayttooikeustaso = + kayttooikeustasoRepository.findOneByKayttooikeustaso(updates[kayttaja.id]!!) + logService.logUpdate(kayttooikeustasoBefore, kayttaja.permission, userId) } else { val kayttajaTunnisteBefore = kayttaja.kayttajaTunniste!!.toDomain() - kayttaja.kayttajaTunniste.role = updates[kayttaja.id]!! + kayttaja.kayttajaTunniste.kayttooikeustaso = updates[kayttaja.id]!! val kayttajaTunnisteAfter = kayttaja.kayttajaTunniste.toDomain() logService.logUpdate(kayttajaTunnisteBefore, kayttajaTunnisteAfter, userId) } @@ -119,7 +120,7 @@ class HankeKayttajaService( /** Check that every user an update was requested for was found as a user of the hanke. */ private fun validateAllKayttajatFound( existingKayttajat: List, - requestedUpdates: Map, + requestedUpdates: Map, hanke: Hanke, ) { with(existingKayttajat.map { it.id }) { @@ -131,49 +132,63 @@ class HankeKayttajaService( } /** - * The user needs to have admin permission (KAIKKI_OIKEUDET role) whenever removing or adding a - * KAIKKI_OIKEUDET from users. + * The user needs to have admin permission (KAIKKI_OIKEUDET kayttooikeustaso) whenever removing + * or adding a KAIKKI_OIKEUDET from users. */ private fun validateAdminPermissionIfNeeded( kayttajat: List, - updates: Map, + updates: Map, deleteAdminPermission: Boolean, userId: String, ) { - val currentRoles = currentRoles(kayttajat) + val currentKayttooikeustasot = currentKayttooikeustasot(kayttajat) if ( - (currentRoles.any { (_, role) -> role == Role.KAIKKI_OIKEUDET } || - updates.any { (_, role) -> role == Role.KAIKKI_OIKEUDET }) && !deleteAdminPermission + (currentKayttooikeustasot.any { (_, kayttooikeustaso) -> + kayttooikeustaso == Kayttooikeustaso.KAIKKI_OIKEUDET + } || + updates.any { (_, kayttooikeustaso) -> + kayttooikeustaso == Kayttooikeustaso.KAIKKI_OIKEUDET + }) && !deleteAdminPermission ) { throw MissingAdminPermissionException(userId) } } /** - * After any change to users' roles, at least one user with KAIKKI_OIKEUDET role in an activated - * permission needs to remain. Otherwise, there's no one who can add that role. + * After any change to users' access levels, at least one user with KAIKKI_OIKEUDET + * kayttooikeustaso in an activated permission needs to remain. Otherwise, there's no one who + * can add that access level. */ private fun validateAdminRemains(hanke: Hanke) { if ( - permissionService.findByHankeId(hanke.id!!).all { it.role.role != Role.KAIKKI_OIKEUDET } + permissionService.findByHankeId(hanke.id!!).all { + it.kayttooikeustaso.kayttooikeustaso != Kayttooikeustaso.KAIKKI_OIKEUDET + } ) { throw NoAdminRemainingException(hanke) } } - /** Finds the current roles of the given HankeKayttajat. Returns an ID -> Role map with */ - private fun currentRoles(kayttajat: List): Map { - val currentRoles = kayttajat.map { it.id to it.deriveRole() } - currentRoles - .filter { (_, role) -> role == null } + /** + * Finds the current access levels of the given HankeKayttajat. Returns an ID -> + * Kayttooikeustaso map. + */ + private fun currentKayttooikeustasot( + kayttajat: List + ): Map { + val currentKayttooikeustasot = kayttajat.map { it.id to it.deriveKayttooikeustaso() } + currentKayttooikeustasot + .filter { (_, kayttooikeustaso) -> kayttooikeustaso == null } .map { (id, _) -> id } .also { missingIds -> if (missingIds.isNotEmpty()) { - throw UsersWithoutRolesException(missingIds) + throw UsersWithoutKayttooikeustasoException(missingIds) } } - return currentRoles.associate { (id, role) -> id to role!! } + return currentKayttooikeustasot.associate { (id, kayttooikeustaso) -> + id to kayttooikeustaso!! + } } private fun createToken(hankeId: Int, contact: UserContact) { @@ -232,7 +247,7 @@ class ChangingOwnPermissionException(userId: String) : class MissingAdminPermissionException(userId: String) : RuntimeException("User doesn't have permission to change admin permissions. userId=$userId") -class UsersWithoutRolesException(missingIds: Collection) : +class UsersWithoutKayttooikeustasoException(missingIds: Collection) : RuntimeException( "Some HankeKayttaja have neither permissions nor user tokens, " + "their ids = ${missingIds.joinToString()}" diff --git a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/KayttajaTunniste.kt b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/KayttajaTunniste.kt index 3f7d25c99..200cf5800 100644 --- a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/KayttajaTunniste.kt +++ b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/KayttajaTunniste.kt @@ -24,7 +24,7 @@ data class KayttajaTunniste( val tunniste: String, val createdAt: OffsetDateTime, val sentAt: OffsetDateTime?, - var role: Role, + var kayttooikeustaso: Kayttooikeustaso, val hankeKayttajaId: UUID? ) : HasId @@ -35,23 +35,24 @@ class KayttajaTunnisteEntity( val tunniste: String, @Column(name = "created_at") val createdAt: OffsetDateTime, @Column(name = "sent_at") val sentAt: OffsetDateTime?, - @Enumerated(EnumType.STRING) var role: Role, + @Enumerated(EnumType.STRING) var kayttooikeustaso: Kayttooikeustaso, @OneToOne(mappedBy = "kayttajaTunniste") val hankeKayttaja: HankeKayttajaEntity? ) { - fun toDomain() = KayttajaTunniste(id, tunniste, createdAt, sentAt, role, hankeKayttaja?.id) + fun toDomain() = + KayttajaTunniste(id, tunniste, createdAt, sentAt, kayttooikeustaso, hankeKayttaja?.id) companion object { private const val tokenLength: Int = 24 private val charPool: List = ('a'..'z') + ('A'..'Z') + ('0'..'9') private val secureRandom: SecureRandom = SecureRandom() - fun create(role: Role = Role.KATSELUOIKEUS) = + fun create() = KayttajaTunnisteEntity( tunniste = randomToken(), createdAt = getCurrentTimeUTC().toOffsetDateTime(), sentAt = null, - role = role, + kayttooikeustaso = Kayttooikeustaso.KATSELUOIKEUS, hankeKayttaja = null ) diff --git a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/Role.kt b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/Kayttooikeustaso.kt similarity index 65% rename from services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/Role.kt rename to services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/Kayttooikeustaso.kt index 722e06686..08c8ee630 100644 --- a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/Role.kt +++ b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/Kayttooikeustaso.kt @@ -10,7 +10,7 @@ import jakarta.persistence.Table import org.springframework.data.jpa.repository.JpaRepository import org.springframework.stereotype.Repository -enum class Role { +enum class Kayttooikeustaso { KAIKKI_OIKEUDET, KAIKKIEN_MUOKKAUS, HANKEMUOKKAUS, @@ -19,14 +19,14 @@ enum class Role { } @Entity -@Table(name = "role") -class RoleEntity( +@Table(name = "kayttooikeustaso") +class KayttooikeustasoEntity( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Int = 0, - @Enumerated(EnumType.STRING) val role: Role, + @Enumerated(EnumType.STRING) val kayttooikeustaso: Kayttooikeustaso, val permissionCode: Long, ) @Repository -interface RoleRepository : JpaRepository { - fun findOneByRole(role: Role): RoleEntity +interface KayttooikeustasoRepository : JpaRepository { + fun findOneByKayttooikeustaso(kayttooikeustaso: Kayttooikeustaso): KayttooikeustasoEntity } diff --git a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/PermissionService.kt b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/PermissionService.kt index 2aac612a6..8e54227c3 100644 --- a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/PermissionService.kt +++ b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/PermissionService.kt @@ -7,7 +7,7 @@ import org.springframework.stereotype.Service @Service class PermissionService( private val permissionRepository: PermissionRepository, - private val roleRepository: RoleRepository + private val kayttooikeustasoRepository: KayttooikeustasoRepository ) { fun findByHankeId(hankeId: Int) = permissionRepository.findAllByHankeId(hankeId) @@ -17,17 +17,27 @@ class PermissionService( } fun hasPermission(hankeId: Int, userId: String, permission: PermissionCode): Boolean { - val role = permissionRepository.findOneByHankeIdAndUserId(hankeId, userId)?.role - return hasPermission(role, permission) + val kayttooikeustaso = + permissionRepository.findOneByHankeIdAndUserId(hankeId, userId)?.kayttooikeustaso + return hasPermission(kayttooikeustaso, permission) } - fun setPermission(hankeId: Int, userId: String, role: Role): PermissionEntity { - val roleEntity = roleRepository.findOneByRole(role) + fun setPermission( + hankeId: Int, + userId: String, + kayttooikeustaso: Kayttooikeustaso + ): PermissionEntity { + val kayttooikeustasoEntity = + kayttooikeustasoRepository.findOneByKayttooikeustaso(kayttooikeustaso) val entity = permissionRepository.findOneByHankeIdAndUserId(hankeId, userId)?.apply { - this.role = roleEntity + this.kayttooikeustaso = kayttooikeustasoEntity } - ?: PermissionEntity(userId = userId, hankeId = hankeId, role = roleEntity) + ?: PermissionEntity( + userId = userId, + hankeId = hankeId, + kayttooikeustaso = kayttooikeustasoEntity + ) return permissionRepository.save(entity) } @@ -39,7 +49,9 @@ class PermissionService( } companion object { - fun hasPermission(role: RoleEntity?, permission: PermissionCode): Boolean = - (role?.permissionCode ?: 0) and permission.code > 0 + fun hasPermission( + kayttooikeustaso: KayttooikeustasoEntity?, + permission: PermissionCode + ): Boolean = (kayttooikeustaso?.permissionCode ?: 0) and permission.code > 0 } } diff --git a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/PermissionUpdate.kt b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/PermissionUpdate.kt index cdfdaf1c9..1c9a29dff 100644 --- a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/PermissionUpdate.kt +++ b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/PermissionUpdate.kt @@ -9,5 +9,5 @@ data class PermissionUpdate( data class PermissionDto( @field:Schema(description = "HankeKayttaja ID") val id: UUID, - @field:Schema(description = "New role in Hanke") val rooli: Role, + @field:Schema(description = "New access level in Hanke") val kayttooikeustaso: Kayttooikeustaso, ) diff --git a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/Permissions.kt b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/Permissions.kt index a14e2a728..277a69663 100644 --- a/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/Permissions.kt +++ b/services/hanke-service/src/main/kotlin/fi/hel/haitaton/hanke/permissions/Permissions.kt @@ -39,9 +39,9 @@ interface PermissionRepository : JpaRepository { */ @Query( "select pe from PermissionEntity pe " + - "inner join pe.role as role " + + "inner join pe.kayttooikeustaso as kayttooikeustaso " + "where pe.userId = :userId " + - "and mod(role.permissionCode / :permissionBit , 2) = 1" + "and mod(kayttooikeustaso.permissionCode / :permissionBit , 2) = 1" ) fun findAllByUserIdAndPermission(userId: String, permissionBit: Long): List } @@ -53,10 +53,10 @@ class PermissionEntity( val userId: String, val hankeId: Int, @ManyToOne(optional = false, fetch = FetchType.EAGER) - @JoinColumn(name = "roleid") - var role: RoleEntity, + @JoinColumn(name = "kayttooikeustaso_id") + var kayttooikeustaso: KayttooikeustasoEntity, ) { - fun toDomain() = Permission(id, userId, hankeId, role.role) + fun toDomain() = Permission(id, userId, hankeId, kayttooikeustaso.kayttooikeustaso) } @JsonView(ChangeLogView::class) @@ -64,5 +64,5 @@ data class Permission( override val id: Int, val userId: String, val hankeId: Int, - var role: Role, + var kayttooikeustaso: Kayttooikeustaso, ) : HasId diff --git a/services/hanke-service/src/main/resources/db/changelog/changesets/044-rename-role-to-kayttooikeustaso.yml b/services/hanke-service/src/main/resources/db/changelog/changesets/044-rename-role-to-kayttooikeustaso.yml new file mode 100644 index 000000000..7feaf5c1d --- /dev/null +++ b/services/hanke-service/src/main/resources/db/changelog/changesets/044-rename-role-to-kayttooikeustaso.yml @@ -0,0 +1,21 @@ +databaseChangeLog: + - changeSet: + id: 044-rename-role-to-kayttooikeustaso + author: Topias Heinonen + comment: Rename role to kayttooikeustaso, since role means something else + changes: + - renameTable: + oldTableName: role + newTableName: kayttooikeustaso + - renameColumn: + tableName: kayttooikeustaso + oldColumnName: role + newColumnName: kayttooikeustaso + - renameColumn: + tableName: permissions + oldColumnName: roleid + newColumnName: kayttooikeustaso_id + - renameColumn: + tableName: kayttaja_tunniste + oldColumnName: role + newColumnName: kayttooikeustaso diff --git a/services/hanke-service/src/main/resources/db/changelog/db.changelog-master.yaml b/services/hanke-service/src/main/resources/db/changelog/db.changelog-master.yaml index 7b636c84e..11184f619 100644 --- a/services/hanke-service/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/services/hanke-service/src/main/resources/db/changelog/db.changelog-master.yaml @@ -115,3 +115,5 @@ databaseChangeLog: file: db/changelog/changesets/042-add-indices-to-hanke-kayttaja.yml - include: file: db/changelog/changesets/043-add-another-index-to-hanke-kayttaja.yml + - include: + file: db/changelog/changesets/044-rename-role-to-kayttooikeustaso.yml diff --git a/services/hanke-service/src/test/kotlin/fi/hel/haitaton/hanke/factory/HankeKayttajaFactory.kt b/services/hanke-service/src/test/kotlin/fi/hel/haitaton/hanke/factory/HankeKayttajaFactory.kt index 3446e6ba5..8d4ce74ae 100644 --- a/services/hanke-service/src/test/kotlin/fi/hel/haitaton/hanke/factory/HankeKayttajaFactory.kt +++ b/services/hanke-service/src/test/kotlin/fi/hel/haitaton/hanke/factory/HankeKayttajaFactory.kt @@ -1,7 +1,7 @@ package fi.hel.haitaton.hanke.factory import fi.hel.haitaton.hanke.permissions.HankeKayttajaDto -import fi.hel.haitaton.hanke.permissions.Role +import fi.hel.haitaton.hanke.permissions.Kayttooikeustaso import java.util.UUID object HankeKayttajaFactory { @@ -12,7 +12,7 @@ object HankeKayttajaFactory { id = UUID.randomUUID(), sahkoposti = "email.$it.address.com", nimi = "test name$it", - rooli = Role.KATSELUOIKEUS, + kayttooikeustaso = Kayttooikeustaso.KATSELUOIKEUS, tunnistautunut = it % 2 == 0 ) }