Skip to content

Commit fd058b5

Browse files
add tests
1 parent 6b2e274 commit fd058b5

File tree

10 files changed

+377
-50
lines changed

10 files changed

+377
-50
lines changed

dataset/src/integrationTest/kotlin/com/cosmotech/dataset/service/DatasetServiceIntegrationTest.kt

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,73 @@ class DatasetServiceIntegrationTest : CsmRedisTestBase() {
977977
assertEquals(dataset1.connector!!.id, dataset2.connector!!.id)
978978
}
979979

980+
@Test
981+
fun `viewerRole has limited vision on security`() {
982+
dataset = makeDatasetWithRole(role = ROLE_VIEWER)
983+
984+
datasetSaved = datasetApiService.createDataset(organizationSaved.id!!, dataset)
985+
assertEquals(
986+
DatasetSecurity(
987+
default = ROLE_NONE, mutableListOf(DatasetAccessControl(TEST_USER_MAIL, ROLE_VIEWER))),
988+
datasetSaved.security)
989+
990+
datasetSaved = datasetApiService.findDatasetById(organizationSaved.id!!, datasetSaved.id!!)
991+
assertEquals(
992+
DatasetSecurity(
993+
default = ROLE_NONE, mutableListOf(DatasetAccessControl(TEST_USER_MAIL, ROLE_VIEWER))),
994+
datasetSaved.security)
995+
996+
datasetSaved = datasetApiService.getVerifiedDataset(organizationSaved.id!!, datasetSaved.id!!)
997+
assertEquals(
998+
DatasetSecurity(
999+
default = ROLE_NONE, mutableListOf(DatasetAccessControl(TEST_USER_MAIL, ROLE_VIEWER))),
1000+
datasetSaved.security)
1001+
1002+
datasetSaved =
1003+
datasetApiService.linkWorkspace(
1004+
organizationSaved.id!!, datasetSaved.id!!, workspaceSaved.id!!)
1005+
assertEquals(
1006+
DatasetSecurity(
1007+
default = ROLE_NONE, mutableListOf(DatasetAccessControl(TEST_USER_MAIL, ROLE_VIEWER))),
1008+
datasetSaved.security)
1009+
1010+
datasetSaved =
1011+
datasetApiService.unlinkWorkspace(
1012+
organizationSaved.id!!, datasetSaved.id!!, workspaceSaved.id!!)
1013+
assertEquals(
1014+
DatasetSecurity(
1015+
default = ROLE_NONE, mutableListOf(DatasetAccessControl(TEST_USER_MAIL, ROLE_VIEWER))),
1016+
datasetSaved.security)
1017+
1018+
datasetSaved =
1019+
datasetApiService.findByOrganizationIdAndDatasetId(
1020+
organizationSaved.id!!, datasetSaved.id!!)!!
1021+
assertEquals(
1022+
DatasetSecurity(
1023+
default = ROLE_NONE, mutableListOf(DatasetAccessControl(TEST_USER_MAIL, ROLE_VIEWER))),
1024+
datasetSaved.security)
1025+
1026+
var datasets = datasetApiService.findAllDatasets(organizationSaved.id!!, 0, 10)
1027+
datasets.forEach {
1028+
assertEquals(
1029+
DatasetSecurity(
1030+
default = ROLE_NONE,
1031+
mutableListOf(DatasetAccessControl(TEST_USER_MAIL, ROLE_VIEWER))),
1032+
datasetSaved.security)
1033+
}
1034+
1035+
datasets =
1036+
datasetApiService.searchDatasets(
1037+
organizationSaved.id!!, DatasetSearch(mutableListOf("dataset")), 0, 10)
1038+
datasets.forEach {
1039+
assertEquals(
1040+
DatasetSecurity(
1041+
default = ROLE_NONE,
1042+
mutableListOf(DatasetAccessControl(TEST_USER_MAIL, ROLE_VIEWER))),
1043+
datasetSaved.security)
1044+
}
1045+
}
1046+
9801047
fun makeConnector(): Connector {
9811048
return Connector(
9821049
key = "connector",

dataset/src/main/kotlin/com/cosmotech/dataset/service/DatasetServiceImpl.kt

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import com.cosmotech.api.rbac.PERMISSION_READ_SECURITY
2626
import com.cosmotech.api.rbac.PERMISSION_WRITE
2727
import com.cosmotech.api.rbac.PERMISSION_WRITE_SECURITY
2828
import com.cosmotech.api.rbac.ROLE_NONE
29+
import com.cosmotech.api.rbac.ROLE_VIEWER
2930
import com.cosmotech.api.rbac.model.RbacAccessControl
3031
import com.cosmotech.api.rbac.model.RbacSecurity
3132
import com.cosmotech.api.security.ROLE_PLATFORM_ADMIN
@@ -81,6 +82,7 @@ import com.google.gson.reflect.TypeToken
8182
import java.io.InputStream
8283
import java.nio.charset.StandardCharsets
8384
import java.time.Instant
85+
import kotlin.jvm.optionals.getOrNull
8486
import kotlinx.coroutines.GlobalScope
8587
import kotlinx.coroutines.launch
8688
import org.apache.commons.compress.archivers.ArchiveStreamFactory
@@ -678,7 +680,11 @@ class DatasetServiceImpl(
678680
datasetId: String
679681
): Dataset? {
680682
organizationService.getVerifiedOrganization(organizationId)
681-
return findBy(organizationId, datasetId)
683+
var dataset = datasetRepository.findBy(organizationId, datasetId).getOrNull()
684+
if (dataset != null) {
685+
dataset = checkReadSecurity(dataset)
686+
}
687+
return dataset
682688
}
683689

684690
override fun addOrUpdateAccessControl(
@@ -1047,7 +1053,6 @@ class DatasetServiceImpl(
10471053
.findDatasetByTags(organizationId, datasetSearch.datasetTags.toSet(), it)
10481054
.toList()
10491055
}
1050-
val currentUser = getCurrentAuthenticatedUserName(csmPlatformProperties)
10511056
datasetList.forEach { checkReadSecurity(it) }
10521057
return datasetList
10531058
}
@@ -1295,16 +1300,27 @@ class DatasetServiceImpl(
12951300
}
12961301

12971302
fun checkReadSecurity(dataset: Dataset): Dataset {
1298-
val username = getCurrentAuthenticatedUserName(csmPlatformProperties)
1303+
var safeDataset = dataset
1304+
val username = getCurrentAccountIdentifier(csmPlatformProperties)
12991305
var userAC = DatasetAccessControl("", "")
13001306
val retrievedAC = dataset.security!!.accessControlList.filter { it.id == username }
1301-
if (retrievedAC.isNotEmpty()) userAC = retrievedAC[0]
1302-
val safeDataset =
1303-
dataset.copy(
1304-
security =
1305-
DatasetSecurity(
1306-
default = dataset.security!!.default,
1307-
accessControlList = mutableListOf(userAC)))
1307+
if (retrievedAC.isNotEmpty()) {
1308+
userAC = retrievedAC[0]
1309+
if (userAC.role == ROLE_VIEWER) {
1310+
safeDataset =
1311+
dataset.copy(
1312+
security =
1313+
DatasetSecurity(
1314+
default = dataset.security!!.default,
1315+
accessControlList = mutableListOf(userAC)))
1316+
}
1317+
} else if (dataset.security!!.default == ROLE_VIEWER) {
1318+
safeDataset =
1319+
dataset.copy(
1320+
security =
1321+
DatasetSecurity(
1322+
default = dataset.security!!.default, accessControlList = mutableListOf()))
1323+
}
13081324
return safeDataset
13091325
}
13101326
}

organization/src/integrationTest/kotlin/com/cosmotech/organization/service/OrganizationServiceIntegrationTest.kt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,41 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
10571057
organizationApiService.getVerifiedOrganization("wrong_orga_id")
10581058
}
10591059
}
1060+
1061+
@Test
1062+
fun `viewerRole has limited vision on security`() {
1063+
val organization = makeOrganization(role = ROLE_VIEWER)
1064+
1065+
var organizationSaved = organizationApiService.registerOrganization(organization)
1066+
assertEquals(
1067+
OrganizationSecurity(
1068+
default = ROLE_NONE,
1069+
mutableListOf(OrganizationAccessControl(TEST_USER_ID, ROLE_VIEWER))),
1070+
organizationSaved.security)
1071+
1072+
organizationSaved = organizationApiService.findOrganizationById(organizationSaved.id!!)
1073+
assertEquals(
1074+
OrganizationSecurity(
1075+
default = ROLE_NONE,
1076+
mutableListOf(OrganizationAccessControl(TEST_USER_ID, ROLE_VIEWER))),
1077+
organizationSaved.security)
1078+
1079+
organizationSaved = organizationApiService.getVerifiedOrganization(organizationSaved.id!!)
1080+
assertEquals(
1081+
OrganizationSecurity(
1082+
default = ROLE_NONE,
1083+
mutableListOf(OrganizationAccessControl(TEST_USER_ID, ROLE_VIEWER))),
1084+
organizationSaved.security)
1085+
1086+
var organizations = organizationApiService.findAllOrganizations(0, 10)
1087+
organizations.forEach {
1088+
assertEquals(
1089+
OrganizationSecurity(
1090+
default = ROLE_NONE,
1091+
mutableListOf(OrganizationAccessControl(TEST_USER_ID, ROLE_VIEWER))),
1092+
organizationSaved.security)
1093+
}
1094+
}
10601095
}
10611096
@Nested
10621097
inner class AsPlatformAdmin {
@@ -2246,6 +2281,24 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
22462281
accessControlList = mutableListOf(OrganizationAccessControl(userName, role))))
22472282
}
22482283

2284+
fun makeOrganization(
2285+
id: String = "organization_id",
2286+
userName: String = TEST_USER_ID,
2287+
role: String = ROLE_ADMIN
2288+
): Organization {
2289+
return Organization(
2290+
id = id,
2291+
name = "Organization Name",
2292+
ownerId = "my.account-tester@cosmotech.com",
2293+
security =
2294+
OrganizationSecurity(
2295+
default = ROLE_NONE,
2296+
accessControlList =
2297+
mutableListOf(
2298+
OrganizationAccessControl(id = TEST_ADMIN_USER_ID, role = "admin"),
2299+
OrganizationAccessControl(id = userName, role = role))))
2300+
}
2301+
22492302
internal fun testFindAllOrganizations(page: Int?, size: Int?, expectedResultSize: Int) {
22502303
val organizationList = organizationApiService.findAllOrganizations(page, size)
22512304
logger.info("Organization list retrieved contains : ${organizationList.size} elements")

organization/src/main/kotlin/com/cosmotech/organization/service/OrganizationServiceImpl.kt

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import com.cosmotech.api.rbac.PERMISSION_READ_SECURITY
1313
import com.cosmotech.api.rbac.PERMISSION_WRITE
1414
import com.cosmotech.api.rbac.PERMISSION_WRITE_SECURITY
1515
import com.cosmotech.api.rbac.ROLE_NONE
16+
import com.cosmotech.api.rbac.ROLE_VIEWER
1617
import com.cosmotech.api.rbac.getAllRolesDefinition
1718
import com.cosmotech.api.rbac.getCommonRolesDefinition
1819
import com.cosmotech.api.rbac.model.RbacAccessControl
@@ -229,16 +230,28 @@ class OrganizationServiceImpl(
229230
}
230231

231232
fun checkReadSecurity(organization: Organization): Organization {
232-
val username = getCurrentAuthenticatedUserName(csmPlatformProperties)
233+
var safeOrganization = organization
234+
val username = getCurrentAccountIdentifier(csmPlatformProperties)
233235
var userAC = OrganizationAccessControl("", "")
234236
val retrievedAC = organization.security!!.accessControlList.filter { it.id == username }
235-
if (retrievedAC.isNotEmpty()) userAC = retrievedAC[0]
236-
val safeOrganization =
237-
organization.copy(
238-
security =
239-
OrganizationSecurity(
240-
default = organization.security!!.default,
241-
accessControlList = mutableListOf(userAC)))
237+
if (retrievedAC.isNotEmpty()) {
238+
userAC = retrievedAC[0]
239+
if (userAC.role == ROLE_VIEWER) {
240+
safeOrganization =
241+
organization.copy(
242+
security =
243+
OrganizationSecurity(
244+
default = organization.security!!.default,
245+
accessControlList = mutableListOf(userAC)))
246+
}
247+
} else if (organization.security!!.default == ROLE_VIEWER) {
248+
safeOrganization =
249+
organization.copy(
250+
security =
251+
OrganizationSecurity(
252+
default = organization.security!!.default,
253+
accessControlList = mutableListOf()))
254+
}
242255
return safeOrganization
243256
}
244257
}

runner/src/integrationTest/kotlin/com/cosmotech/runner/service/RunnerServiceIntegrationTest.kt

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,33 @@ class RunnerServiceIntegrationTest : CsmRedisTestBase() {
10271027
assertEquals(expectedRunId, lastRunId)
10281028
}
10291029

1030+
@Test
1031+
fun `viewerRole has limited vision on security`() {
1032+
every { getCurrentAccountIdentifier(any()) } returns defaultName
1033+
runner = makeRunner(userName = defaultName, role = ROLE_VIEWER)
1034+
1035+
runnerSaved = runnerApiService.createRunner(organizationSaved.id!!, workspaceSaved.id!!, runner)
1036+
assertEquals(
1037+
RunnerSecurity(
1038+
default = ROLE_NONE, mutableListOf(RunnerAccessControl(defaultName, ROLE_VIEWER))),
1039+
runnerSaved.security)
1040+
1041+
runnerSaved =
1042+
runnerApiService.getRunner(organizationSaved.id!!, workspaceSaved.id!!, runnerSaved.id!!)
1043+
assertEquals(
1044+
RunnerSecurity(
1045+
default = ROLE_NONE, mutableListOf(RunnerAccessControl(defaultName, ROLE_VIEWER))),
1046+
runnerSaved.security)
1047+
1048+
val runners = runnerApiService.listRunners(organizationSaved.id!!, workspaceSaved.id!!, 0, 10)
1049+
runners.forEach {
1050+
assertEquals(
1051+
RunnerSecurity(
1052+
default = ROLE_NONE, mutableListOf(RunnerAccessControl(defaultName, ROLE_VIEWER))),
1053+
runnerSaved.security)
1054+
}
1055+
}
1056+
10301057
private fun makeConnector(name: String = "name"): Connector {
10311058
return Connector(
10321059
key = UUID.randomUUID().toString(),
@@ -1057,7 +1084,8 @@ class RunnerServiceIntegrationTest : CsmRedisTestBase() {
10571084
default = ROLE_NONE,
10581085
accessControlList =
10591086
mutableListOf(
1060-
DatasetAccessControl(id = CONNECTED_ADMIN_USER, role = ROLE_ADMIN))))
1087+
DatasetAccessControl(id = CONNECTED_ADMIN_USER, role = ROLE_ADMIN),
1088+
DatasetAccessControl(defaultName, ROLE_USER))))
10611089
}
10621090

10631091
fun makeSolution(organizationId: String = organizationSaved.id!!): Solution {
@@ -1090,7 +1118,8 @@ class RunnerServiceIntegrationTest : CsmRedisTestBase() {
10901118
default = ROLE_NONE,
10911119
accessControlList =
10921120
mutableListOf(
1093-
SolutionAccessControl(id = CONNECTED_ADMIN_USER, role = ROLE_ADMIN))))
1121+
SolutionAccessControl(id = CONNECTED_ADMIN_USER, role = ROLE_ADMIN),
1122+
SolutionAccessControl(id = defaultName, role = ROLE_USER))))
10941123
}
10951124

10961125
fun makeOrganization(

runner/src/main/kotlin/com/cosmotech/runner/service/RunnerApiServiceImpl.kt

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ import com.cosmotech.api.rbac.PERMISSION_LAUNCH
1010
import com.cosmotech.api.rbac.PERMISSION_READ_SECURITY
1111
import com.cosmotech.api.rbac.PERMISSION_WRITE
1212
import com.cosmotech.api.rbac.PERMISSION_WRITE_SECURITY
13+
import com.cosmotech.api.rbac.ROLE_VIEWER
1314
import com.cosmotech.api.rbac.getRunnerRolesDefinition
1415
import com.cosmotech.api.utils.constructPageRequest
15-
import com.cosmotech.api.utils.getCurrentAuthenticatedUserName
16+
import com.cosmotech.api.utils.getCurrentAccountIdentifier
1617
import com.cosmotech.runner.RunnerApiServiceInterface
1718
import com.cosmotech.runner.domain.CreatedRun
1819
import com.cosmotech.runner.domain.Runner
@@ -241,15 +242,27 @@ internal class RunnerApiServiceImpl(
241242
}
242243

243244
fun checkReadSecurity(runner: Runner): Runner {
244-
val username = getCurrentAuthenticatedUserName(csmPlatformProperties)
245+
var safeRunner = runner
246+
val username = getCurrentAccountIdentifier(csmPlatformProperties)
245247
var userAC = RunnerAccessControl("", "")
246248
val retrievedAC = runner.security!!.accessControlList.filter { it.id == username }
247-
if (retrievedAC.isNotEmpty()) userAC = retrievedAC[0]
248-
val safeRunner =
249-
runner.copy(
250-
security =
251-
RunnerSecurity(
252-
default = runner.security!!.default, accessControlList = mutableListOf(userAC)))
249+
if (retrievedAC.isNotEmpty()) {
250+
userAC = retrievedAC[0]
251+
if (userAC.role == ROLE_VIEWER) {
252+
safeRunner =
253+
runner.copy(
254+
security =
255+
RunnerSecurity(
256+
default = runner.security!!.default,
257+
accessControlList = mutableListOf(userAC)))
258+
}
259+
} else if (runner.security!!.default == ROLE_VIEWER) {
260+
safeRunner =
261+
runner.copy(
262+
security =
263+
RunnerSecurity(
264+
default = runner.security!!.default, accessControlList = mutableListOf()))
265+
}
253266
return safeRunner
254267
}
255268
}

0 commit comments

Comments
 (0)