Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import com.redis.testcontainers.RedisStackContainer
import io.mockk.every
import io.mockk.junit5.MockKExtension
import io.mockk.mockkStatic
import io.mockk.verify
import java.time.Instant
import java.util.*
import kotlin.test.*
Expand Down Expand Up @@ -1095,6 +1096,56 @@ class RunnerServiceIntegrationTest : CsmRedisTestBase() {
}
}

@Test
fun `when sharing a runner, the linked dataset default security should be set to at least viewer if the dataset isn't main`() {
runnerSaved.datasetList!!.removeLast()
listOf(ROLE_NONE, ROLE_VIEWER, ROLE_USER, ROLE_EDITOR, ROLE_ADMIN).forEach { role ->
var linkedDataset =
datasetApiService.createDataset(
organizationSaved.id!!, makeDataset(isMain = false, default = role))
runnerSaved.datasetList!!.add(linkedDataset.id!!)
linkedDataset =
datasetApiService.createDataset(
organizationSaved.id!!, makeDataset(isMain = true, default = role))
runnerSaved.datasetList!!.add(linkedDataset.id!!)
}
runnerSaved =
runnerApiService.updateRunner(
organizationSaved.id!!, workspaceSaved.id!!, runnerSaved.id!!, runnerSaved)

runnerApiService.setRunnerDefaultSecurity(
organizationSaved.id!!, workspaceSaved.id!!, runnerSaved.id!!, RunnerRole(ROLE_EDITOR))

verify(exactly = 1) {
datasetApiService.setDatasetDefaultSecurity(any(), any(), DatasetRole(ROLE_VIEWER))
}
}

@Test
fun `when stopping sharing a scenario, the dataset default security should be set to none it's not higher than viewer and the dataset isn't main`() {
runnerSaved.datasetList!!.removeLast()
listOf(ROLE_NONE, ROLE_VIEWER, ROLE_USER, ROLE_EDITOR, ROLE_ADMIN).forEach { role ->
var linkedDataset =
datasetApiService.createDataset(
organizationSaved.id!!, makeDataset(isMain = false, default = role))
runnerSaved.datasetList!!.add(linkedDataset.id!!)
linkedDataset =
datasetApiService.createDataset(
organizationSaved.id!!, makeDataset(isMain = true, default = role))
runnerSaved.datasetList!!.add(linkedDataset.id!!)
}
runnerSaved =
runnerApiService.updateRunner(
organizationSaved.id!!, workspaceSaved.id!!, runnerSaved.id!!, runnerSaved)

runnerApiService.setRunnerDefaultSecurity(
organizationSaved.id!!, workspaceSaved.id!!, runnerSaved.id!!, RunnerRole(ROLE_NONE))

verify(exactly = 1) {
datasetApiService.setDatasetDefaultSecurity(any(), any(), DatasetRole(ROLE_NONE))
}
}

private fun makeConnector(name: String = "name"): Connector {
return Connector(
key = UUID.randomUUID().toString(),
Expand All @@ -1107,7 +1158,9 @@ class RunnerServiceIntegrationTest : CsmRedisTestBase() {
fun makeDataset(
organizationId: String = organizationSaved.id!!,
name: String = "name",
connector: Connector = connectorSaved
connector: Connector = connectorSaved,
isMain: Boolean = true,
default: String = ROLE_NONE
): Dataset {
return Dataset(
name = name,
Expand All @@ -1120,9 +1173,10 @@ class RunnerServiceIntegrationTest : CsmRedisTestBase() {
name = connector.name,
version = connector.version,
),
main = isMain,
security =
DatasetSecurity(
default = ROLE_NONE,
default = default,
accessControlList =
mutableListOf(
DatasetAccessControl(id = CONNECTED_ADMIN_USER, role = ROLE_ADMIN),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.cosmotech.api.rbac.PERMISSION_READ_SECURITY
import com.cosmotech.api.rbac.ROLE_NONE
import com.cosmotech.api.rbac.ROLE_USER
import com.cosmotech.api.rbac.ROLE_VALIDATOR
import com.cosmotech.api.rbac.ROLE_VIEWER
import com.cosmotech.api.rbac.RolesDefinition
import com.cosmotech.api.rbac.getScenarioRolesDefinition
import com.cosmotech.api.rbac.model.RbacAccessControl
Expand All @@ -26,6 +27,7 @@ import com.cosmotech.api.utils.getCurrentAuthenticatedRoles
import com.cosmotech.api.utils.getCurrentAuthenticatedUserName
import com.cosmotech.dataset.DatasetApiServiceInterface
import com.cosmotech.dataset.domain.Dataset
import com.cosmotech.dataset.domain.DatasetRole
import com.cosmotech.dataset.service.getRbac
import com.cosmotech.organization.OrganizationApiServiceInterface
import com.cosmotech.organization.domain.Organization
Expand Down Expand Up @@ -506,6 +508,34 @@ class RunnerService(
// create a rbacSecurity object from runner Rbac by changing default value
val rbacSecurity = csmRbac.setDefault(this.getRbacSecurity(), role, this.roleDefinition)
this.setRbacSecurity(rbacSecurity)
// this.runner.datasetList!!
// .mapNotNull {
// datasetApiService.findByOrganizationIdAndDatasetId(this.runner.organizationId!!,
// it)
// }
// .forEach { dataset ->
updateLinkedDatasetDefaultSecurity(role)
// }
}

private fun updateLinkedDatasetDefaultSecurity(role: String) {
var datasetRole = ROLE_NONE
if (role != ROLE_NONE) datasetRole = ROLE_VIEWER
this.runner.datasetList!!.forEach { datasetId ->
val linkedDataset =
datasetApiService.findDatasetById(this.runner.organizationId!!, datasetId)
// We do not want to lower the default security if it's higher than viewer
if (linkedDataset.security!!.default != ROLE_NONE && datasetRole == ROLE_VIEWER)
return@forEach Unit
if (linkedDataset.security!!.default != ROLE_NONE && datasetRole == ROLE_NONE)
return@forEach Unit
// Filter on dataset copy (because we do not want to update main dataset as it can be shared
// between scenarios)
if (linkedDataset.main != true) {
datasetApiService.setDatasetDefaultSecurity(
this.runner.organizationId!!, datasetId, DatasetRole(datasetRole))
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.junit5.MockKExtension
import io.mockk.mockkStatic
import io.mockk.verify
import java.time.Instant
import java.util.*
import kotlin.test.assertEquals
Expand Down Expand Up @@ -1257,6 +1258,56 @@ class ScenarioServiceIntegrationTest : CsmRedisTestBase() {
}
}

@Test
fun `when sharing a scenario, the linked dataset default security should be set to at least viewer if the dataset isn't main`() {
scenarioSaved.datasetList!!.removeLast()
listOf(ROLE_NONE, ROLE_VIEWER, ROLE_USER, ROLE_EDITOR, ROLE_ADMIN).forEach { role ->
var linkedDataset =
datasetApiService.createDataset(
organizationSaved.id!!, makeDataset(isMain = false, default = role))
scenarioSaved.datasetList!!.add(linkedDataset.id!!)
linkedDataset =
datasetApiService.createDataset(
organizationSaved.id!!, makeDataset(isMain = true, default = role))
scenarioSaved.datasetList!!.add(linkedDataset.id!!)
}
scenarioSaved =
scenarioApiService.updateScenario(
organizationSaved.id!!, workspaceSaved.id!!, scenarioSaved.id!!, scenarioSaved)

scenarioApiService.setScenarioDefaultSecurity(
organizationSaved.id!!, workspaceSaved.id!!, scenarioSaved.id!!, ScenarioRole(ROLE_EDITOR))

verify(exactly = 1) {
datasetApiService.setDatasetDefaultSecurity(any(), any(), DatasetRole(ROLE_VIEWER))
}
}

@Test
fun `when stopping sharing a scenario, the dataset default security should be set to none it's not higher than viewer and the dataset isn't main`() {
scenarioSaved.datasetList!!.removeLast()
listOf(ROLE_NONE, ROLE_VIEWER, ROLE_USER, ROLE_EDITOR, ROLE_ADMIN).forEach { role ->
var linkedDataset =
datasetApiService.createDataset(
organizationSaved.id!!, makeDataset(isMain = false, default = role))
scenarioSaved.datasetList!!.add(linkedDataset.id!!)
linkedDataset =
datasetApiService.createDataset(
organizationSaved.id!!, makeDataset(isMain = true, default = role))
scenarioSaved.datasetList!!.add(linkedDataset.id!!)
}
scenarioSaved =
scenarioApiService.updateScenario(
organizationSaved.id!!, workspaceSaved.id!!, scenarioSaved.id!!, scenarioSaved)

scenarioApiService.setScenarioDefaultSecurity(
organizationSaved.id!!, workspaceSaved.id!!, scenarioSaved.id!!, ScenarioRole(ROLE_NONE))

verify(exactly = 1) {
datasetApiService.setDatasetDefaultSecurity(any(), any(), DatasetRole(ROLE_NONE))
}
}

private fun makeWorkspaceEventHubInfo(eventHubAvailable: Boolean): WorkspaceEventHubInfo {
return WorkspaceEventHubInfo(
eventHubNamespace = "eventHubNamespace",
Expand Down Expand Up @@ -1284,7 +1335,8 @@ class ScenarioServiceIntegrationTest : CsmRedisTestBase() {
name: String = "name",
connector: Connector = connectorSaved,
sourceType: DatasetSourceType = DatasetSourceType.Twincache,
isMain: Boolean = true
isMain: Boolean = true,
default: String = ROLE_NONE
): Dataset {
return Dataset(
name = name,
Expand All @@ -1301,7 +1353,7 @@ class ScenarioServiceIntegrationTest : CsmRedisTestBase() {
main = isMain,
security =
DatasetSecurity(
default = ROLE_NONE,
default = default,
accessControlList =
mutableListOf(
DatasetAccessControl(id = CONNECTED_ADMIN_USER, role = ROLE_ADMIN))))
Expand Down Expand Up @@ -1397,6 +1449,7 @@ class ScenarioServiceIntegrationTest : CsmRedisTestBase() {
name: String = "name",
datasetList: MutableList<String>? = mutableListOf(),
parentId: String? = null,
defaultSecurity: String = ROLE_NONE,
userName: String = "roleName",
role: String = ROLE_USER,
validationStatus: ScenarioValidationStatus = ScenarioValidationStatus.Draft,
Expand All @@ -1416,7 +1469,7 @@ class ScenarioServiceIntegrationTest : CsmRedisTestBase() {
parametersValues = parametersValues,
security =
ScenarioSecurity(
ROLE_NONE,
defaultSecurity,
mutableListOf(
ScenarioAccessControl(CONNECTED_ADMIN_USER, ROLE_ADMIN),
ScenarioAccessControl(userName, role))))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.cosmotech.api.rbac.PERMISSION_DELETE
import com.cosmotech.api.rbac.PERMISSION_READ_SECURITY
import com.cosmotech.api.rbac.PERMISSION_WRITE
import com.cosmotech.api.rbac.PERMISSION_WRITE_SECURITY
import com.cosmotech.api.rbac.ROLE_NONE
import com.cosmotech.api.rbac.ROLE_USER
import com.cosmotech.api.rbac.ROLE_VALIDATOR
import com.cosmotech.api.rbac.ROLE_VIEWER
Expand All @@ -40,6 +41,7 @@ import com.cosmotech.api.utils.findAllPaginated
import com.cosmotech.api.utils.getCurrentAccountIdentifier
import com.cosmotech.api.utils.getCurrentAuthenticatedUserName
import com.cosmotech.dataset.DatasetApiServiceInterface
import com.cosmotech.dataset.domain.DatasetRole
import com.cosmotech.dataset.domain.IngestionStatusEnum
import com.cosmotech.dataset.domain.SubDatasetGraphQuery
import com.cosmotech.dataset.service.getRbac
Expand Down Expand Up @@ -996,6 +998,7 @@ internal class ScenarioServiceImpl(
csmRbac.setDefault(scenario.getRbac(), scenarioRole.role, scenarioPermissions)
scenario.setRbac(rbacSecurity)
upsertScenarioData(scenario)
setLinkedDatasetDefaultSecurity(organizationId, scenario, scenarioRole.role)
return scenario.security as ScenarioSecurity
}

Expand Down Expand Up @@ -1158,6 +1161,27 @@ internal class ScenarioServiceImpl(
}
}

fun setLinkedDatasetDefaultSecurity(
organizationId: String,
scenario: Scenario,
scenarioRole: String
) {
var datasetRole = ROLE_NONE
if (scenarioRole != ROLE_NONE) datasetRole = ROLE_VIEWER
scenario.datasetList!!.forEach { datasetId ->
val dataset = datasetService.findDatasetById(organizationId, datasetId)
// We do not want to lower the default security if it's higher than viewer
if (dataset.security!!.default != ROLE_NONE && datasetRole == ROLE_VIEWER) return Unit
if (dataset.security!!.default != ROLE_NONE && datasetRole == ROLE_NONE) return Unit
// Filter on dataset copy (because we do not want to update main dataset as it can be shared
// between scenarios)
if (dataset.main != true) {
datasetService.setDatasetDefaultSecurity(
organizationId, datasetId, DatasetRole(datasetRole))
}
}
}

override fun getScenarioSecurityUsers(
organizationId: String,
workspaceId: String,
Expand Down
Loading