Skip to content

Commit d817388

Browse files
committed
[PROD-13443] Make sure to have an admin when creating a resource
1 parent b90de48 commit d817388

File tree

8 files changed

+46
-156
lines changed

8 files changed

+46
-156
lines changed

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

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import com.cosmotech.api.rbac.PERMISSION_DELETE
2424
import com.cosmotech.api.rbac.PERMISSION_READ_SECURITY
2525
import com.cosmotech.api.rbac.PERMISSION_WRITE
2626
import com.cosmotech.api.rbac.PERMISSION_WRITE_SECURITY
27-
import com.cosmotech.api.rbac.ROLE_ADMIN
2827
import com.cosmotech.api.rbac.ROLE_NONE
2928
import com.cosmotech.api.rbac.model.RbacAccessControl
3029
import com.cosmotech.api.rbac.model.RbacSecurity
@@ -184,21 +183,7 @@ class DatasetServiceImpl(
184183
val existingConnector = connectorService.findConnectorById(dataset.connector!!.id!!)
185184
logger.debug("Found connector: {}", existingConnector)
186185

187-
var datasetSecurity = dataset.security
188-
if (datasetSecurity == null) {
189-
datasetSecurity = initSecurity(getCurrentAccountIdentifier(this.csmPlatformProperties))
190-
} else {
191-
val accessControls = mutableListOf<String>()
192-
datasetSecurity.accessControlList.forEach {
193-
if (!accessControls.contains(it.id)) {
194-
accessControls.add(it.id)
195-
} else {
196-
throw IllegalArgumentException("User $it is referenced multiple times in the security")
197-
}
198-
}
199-
}
200-
201-
val datasetCopy =
186+
val createdDataset =
202187
dataset.copy(
203188
id = idGenerator.generate("dataset"),
204189
twingraphId = twingraphId,
@@ -209,13 +194,14 @@ class DatasetServiceImpl(
209194
ingestionStatus = IngestionStatusEnum.NONE,
210195
twincacheStatus = TwincacheStatusEnum.EMPTY,
211196
ownerId = getCurrentAuthenticatedUserName(csmPlatformProperties),
212-
organizationId = organizationId,
213-
security = datasetSecurity)
214-
datasetCopy.connector!!.apply {
197+
organizationId = organizationId)
198+
createdDataset.setRbac(csmRbac.initSecurity(dataset.getRbac()))
199+
createdDataset.connector!!.apply {
215200
name = existingConnector.name
216201
version = existingConnector.version
217202
}
218-
return datasetRepository.save(datasetCopy)
203+
204+
return datasetRepository.save(createdDataset)
219205
}
220206

221207
override fun createSubDataset(
@@ -1241,12 +1227,6 @@ class DatasetServiceImpl(
12411227
}
12421228
}
12431229

1244-
private fun initSecurity(userId: String): DatasetSecurity {
1245-
return DatasetSecurity(
1246-
default = ROLE_NONE,
1247-
accessControlList = mutableListOf(DatasetAccessControl(userId, ROLE_ADMIN)))
1248-
}
1249-
12501230
fun Dataset.getRbac(): RbacSecurity {
12511231
return RbacSecurity(
12521232
this.id,

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

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,10 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
120120

121121
@Test
122122
fun `findAllOrganizations with correct values and RBAC for current user`() {
123-
123+
runAsDifferentOrganizationUser()
124124
val numberOfOrganizationCreated = createOrganizationsWithAllCombinationOfRole(TEST_USER_ID)
125+
126+
runAsOrganizationUser()
125127
// This number represents the amount of Organization that test.user can read regarding RBAC
126128
// This is typically all simple combinations except "securityRole to none"
127129
// We have 36 combinations per user in batchOrganizationCreationWithRBAC
@@ -131,9 +133,11 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
131133

132134
@Test
133135
fun `findAllOrganizations with correct values and no RBAC for current user`() {
134-
136+
runAsDifferentOrganizationUser()
135137
val numberOfOrganizationCreated =
136138
createOrganizationsWithAllCombinationOfRole(OTHER_TEST_USER_ID)
139+
140+
runAsOrganizationUser()
137141
// This number represents the amount of Organization that test.user can read regarding RBAC
138142
// We have 36 combinations per user in batchOrganizationCreationWithRBAC
139143
// securityRole does not refer to test.user
@@ -224,7 +228,8 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
224228
OrganizationSecurity(
225229
default = ROLE_USER,
226230
mutableListOf(
227-
OrganizationAccessControl(id = OTHER_TEST_USER_ID, role = ROLE_NONE))),
231+
OrganizationAccessControl(id = OTHER_TEST_USER_ID, role = ROLE_NONE),
232+
OrganizationAccessControl(id = TEST_USER_ID, role = ROLE_ADMIN))),
228233
organizationRegistered.security)
229234
assertEquals(name, organizationRegistered.name)
230235
assertTrue(organizationRegistered.id!!.startsWith("o-"))
@@ -254,7 +259,8 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
254259
assertThrows<CsmAccessForbiddenException> {
255260
val name = "o-connector-test-1"
256261
val organizationToRegister =
257-
createTestOrganizationWithSimpleSecurity(name, OTHER_TEST_USER_ID, ROLE_USER, ROLE_NONE)
262+
createTestOrganizationWithSimpleSecurity(
263+
name, OTHER_TEST_USER_ID, ROLE_USER, ROLE_ADMIN)
258264
val organizationRegistered =
259265
organizationApiService.registerOrganization(organizationToRegister)
260266
organizationApiService.unregisterOrganization(organizationRegistered.id!!)
@@ -1268,7 +1274,7 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
12681274
runAsOrganizationUser()
12691275
val orgaUsers =
12701276
organizationApiService.getOrganizationSecurityUsers(organizationRegistered.id!!)
1271-
assertEquals(listOf(TEST_USER_ID), orgaUsers)
1277+
assertEquals(listOf(TEST_USER_ID, OTHER_TEST_USER_ID), orgaUsers)
12721278
}
12731279

12741280
@Test
@@ -1418,7 +1424,8 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
14181424
OrganizationSecurity(
14191425
default = ROLE_USER,
14201426
mutableListOf(
1421-
OrganizationAccessControl(id = OTHER_TEST_USER_ID, role = ROLE_NONE))),
1427+
OrganizationAccessControl(id = OTHER_TEST_USER_ID, role = ROLE_NONE),
1428+
OrganizationAccessControl(id = TEST_ADMIN_USER_ID, role = ROLE_ADMIN))),
14221429
organizationRegistered.security)
14231430
assertEquals(name, organizationRegistered.name)
14241431
assertTrue(organizationRegistered.id!!.startsWith("o-"))
@@ -2557,7 +2564,7 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
25572564
runAsPlatformAdmin()
25582565
val orgaUsers =
25592566
organizationApiService.getOrganizationSecurityUsers(organizationRegistered.id!!)
2560-
assertEquals(listOf(TEST_USER_ID), orgaUsers)
2567+
assertEquals(listOf(TEST_USER_ID, OTHER_TEST_USER_ID), orgaUsers)
25612568
}
25622569

25632570
@Test
@@ -2570,7 +2577,7 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
25702577
runAsPlatformAdmin()
25712578
val orgaUsers =
25722579
organizationApiService.getOrganizationSecurityUsers(organizationRegistered.id!!)
2573-
assertEquals(listOf(TEST_USER_ID), orgaUsers)
2580+
assertEquals(listOf(TEST_USER_ID, OTHER_TEST_USER_ID), orgaUsers)
25742581
}
25752582

25762583
@Test

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

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import com.cosmotech.api.rbac.PERMISSION_READ
1212
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
15-
import com.cosmotech.api.rbac.ROLE_ADMIN
1615
import com.cosmotech.api.rbac.ROLE_NONE
1716
import com.cosmotech.api.rbac.getAllRolesDefinition
1817
import com.cosmotech.api.rbac.getCommonRolesDefinition
@@ -80,33 +79,19 @@ class OrganizationServiceImpl(
8079
}
8180

8281
override fun registerOrganization(organization: Organization): Organization {
83-
logger.trace("Registering organization : {}", organization)
82+
logger.trace("Registering organization: {}", organization)
8483

8584
if (organization.name.isNullOrBlank()) {
8685
throw IllegalArgumentException("Organization name must not be null or blank")
8786
}
8887

89-
val newOrganizationId = idGenerator.generate("organization")
90-
var organizationSecurity = organization.security
91-
if (organizationSecurity == null) {
92-
val currentUser = getCurrentAccountIdentifier(this.csmPlatformProperties)
93-
organizationSecurity = initSecurity(currentUser)
94-
} else {
95-
val accessControls = mutableListOf<String>()
96-
organizationSecurity.accessControlList.forEach {
97-
if (!accessControls.contains(it.id)) {
98-
accessControls.add(it.id)
99-
} else {
100-
throw IllegalArgumentException("User $it is referenced multiple times in the security")
101-
}
102-
}
103-
}
104-
105-
return organizationRepository.save(
88+
val createdOrganization =
10689
organization.copy(
107-
id = newOrganizationId,
108-
ownerId = getCurrentAuthenticatedUserName(csmPlatformProperties),
109-
security = organizationSecurity))
90+
id = idGenerator.generate("organization"),
91+
ownerId = getCurrentAuthenticatedUserName(csmPlatformProperties))
92+
createdOrganization.setRbac(csmRbac.initSecurity(organization.getRbac()))
93+
94+
return organizationRepository.save(createdOrganization)
11095
}
11196

11297
override fun unregisterOrganization(organizationId: String) {
@@ -313,12 +298,6 @@ class OrganizationServiceImpl(
313298

314299
return existingOrganizationService
315300
}
316-
317-
private fun initSecurity(userId: String): OrganizationSecurity {
318-
return OrganizationSecurity(
319-
default = ROLE_NONE,
320-
accessControlList = mutableListOf(OrganizationAccessControl(userId, ROLE_ADMIN)))
321-
}
322301
}
323302

324303
fun Organization.getRbac(): RbacSecurity {

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,7 @@ internal class RunnerApiServiceImpl(
3636
.inWorkspace(workspaceId)
3737
.userHasPermissionOnWorkspace(PERMISSION_CREATE_CHILDREN)
3838
val runnerInstance =
39-
runnerService
40-
.getNewInstance()
41-
.setValueFrom(runner)
42-
.initSecurity()
43-
.initParameters()
44-
.setSecurityFrom(runner)
39+
runnerService.getNewInstance().setValueFrom(runner).initSecurity(runner).initParameters()
4540

4641
return runnerService.saveInstance(runnerInstance)
4742
}

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

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import com.cosmotech.api.exceptions.CsmClientException
1111
import com.cosmotech.api.exceptions.CsmResourceNotFoundException
1212
import com.cosmotech.api.rbac.CsmRbac
1313
import com.cosmotech.api.rbac.PERMISSION_READ
14-
import com.cosmotech.api.rbac.ROLE_ADMIN
1514
import com.cosmotech.api.rbac.ROLE_NONE
1615
import com.cosmotech.api.rbac.ROLE_USER
1716
import com.cosmotech.api.rbac.ROLE_VALIDATOR
@@ -201,21 +200,13 @@ class RunnerService(
201200
}
202201
}
203202

204-
fun setSecurityFrom(runner: Runner): RunnerInstance = apply {
205-
val rbacSecurity = extractRbacSecurity(runner) ?: return@apply
206-
this.setRbacSecurity(rbacSecurity)
207-
}
208-
209203
fun setLastRunId(runInfo: String) {
210204
this.runner.lastRunId = runInfo
211205
}
212206

213-
fun initSecurity(): RunnerInstance = apply {
214-
val userId = getCurrentAccountIdentifier(csmPlatformProperties)
215-
this.runner.security =
216-
RunnerSecurity(
217-
default = ROLE_NONE,
218-
accessControlList = mutableListOf(RunnerAccessControl(userId, ROLE_ADMIN)))
207+
fun initSecurity(runner: Runner): RunnerInstance = apply {
208+
val rbacSecurity = csmRbac.initSecurity(extractRbacSecurity(runner))
209+
setRbacSecurity(rbacSecurity)
219210
}
220211

221212
fun initParameters(): RunnerInstance = apply {
@@ -281,7 +272,7 @@ class RunnerService(
281272
}
282273

283274
private fun getRbacSecurity(): RbacSecurity {
284-
return extractRbacSecurity(this.runner)!!
275+
return extractRbacSecurity(this.runner)
285276
}
286277

287278
private fun setRbacSecurity(rbacSecurity: RbacSecurity) {
@@ -294,10 +285,7 @@ class RunnerService(
294285
.toMutableList())
295286
}
296287

297-
private fun extractRbacSecurity(runner: Runner): RbacSecurity? {
298-
if (runner.security == null) {
299-
return null
300-
}
288+
private fun extractRbacSecurity(runner: Runner): RbacSecurity {
301289
return RbacSecurity(
302290
runner.id,
303291
runner.security?.default ?: ROLE_NONE,

scenario/src/main/kotlin/com/cosmotech/scenario/service/ScenarioServiceImpl.kt

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ import com.cosmotech.api.rbac.PERMISSION_DELETE
2727
import com.cosmotech.api.rbac.PERMISSION_READ_SECURITY
2828
import com.cosmotech.api.rbac.PERMISSION_WRITE
2929
import com.cosmotech.api.rbac.PERMISSION_WRITE_SECURITY
30-
import com.cosmotech.api.rbac.ROLE_ADMIN
31-
import com.cosmotech.api.rbac.ROLE_NONE
3230
import com.cosmotech.api.rbac.ROLE_USER
3331
import com.cosmotech.api.rbac.ROLE_VALIDATOR
3432
import com.cosmotech.api.rbac.ROLE_VIEWER
@@ -170,20 +168,6 @@ internal class ScenarioServiceImpl(
170168
parentId, solution, runTemplate, parent, scenario, newParametersValuesList)
171169
}
172170

173-
var scenarioSecurity = scenario.security
174-
if (scenarioSecurity == null) {
175-
scenarioSecurity = initSecurity(getCurrentAccountIdentifier(this.csmPlatformProperties))
176-
} else {
177-
val accessControls = mutableListOf<String>()
178-
scenarioSecurity.accessControlList.forEach {
179-
if (!accessControls.contains(it.id)) {
180-
accessControls.add(it.id)
181-
} else {
182-
throw IllegalArgumentException("User $it is referenced multiple times in the security")
183-
}
184-
}
185-
}
186-
187171
if (workspace.datasetCopy == true) {
188172
datasetList =
189173
datasetList
@@ -221,8 +205,8 @@ internal class ScenarioServiceImpl(
221205
datasetList = datasetList,
222206
rootId = rootId,
223207
parametersValues = newParametersValuesList,
224-
validationStatus = ScenarioValidationStatus.Draft,
225-
security = scenarioSecurity)
208+
validationStatus = ScenarioValidationStatus.Draft)
209+
scenarioToSave.setRbac(csmRbac.initSecurity(scenario.getRbac()))
226210

227211
scenarioRepository.save(scenarioToSave)
228212

@@ -1137,12 +1121,6 @@ internal class ScenarioServiceImpl(
11371121
return scenario
11381122
}
11391123

1140-
private fun initSecurity(userId: String): ScenarioSecurity {
1141-
return ScenarioSecurity(
1142-
default = ROLE_NONE,
1143-
accessControlList = mutableListOf(ScenarioAccessControl(userId, ROLE_ADMIN)))
1144-
}
1145-
11461124
internal fun checkInternalResultDataServiceConfiguration() {
11471125
if (csmPlatformProperties.internalResultServices?.enabled == true) {
11481126
throw NotImplementedException(notImplementedExceptionMessage)

solution/src/main/kotlin/com/cosmotech/solution/service/SolutionServiceImpl.kt

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import com.cosmotech.api.rbac.PERMISSION_DELETE
1515
import com.cosmotech.api.rbac.PERMISSION_READ_SECURITY
1616
import com.cosmotech.api.rbac.PERMISSION_WRITE
1717
import com.cosmotech.api.rbac.PERMISSION_WRITE_SECURITY
18-
import com.cosmotech.api.rbac.ROLE_ADMIN
1918
import com.cosmotech.api.rbac.ROLE_NONE
2019
import com.cosmotech.api.rbac.model.RbacAccessControl
2120
import com.cosmotech.api.rbac.model.RbacSecurity
@@ -204,26 +203,15 @@ class SolutionServiceImpl(
204203

205204
override fun createSolution(organizationId: String, solution: Solution): Solution {
206205
organizationApiService.getVerifiedOrganization(organizationId, PERMISSION_CREATE_CHILDREN)
207-
var solutionSecurity = solution.security
208-
if (solutionSecurity == null) {
209-
solutionSecurity = initSecurity(getCurrentAccountIdentifier(this.csmPlatformProperties))
210-
} else {
211-
val accessControls = mutableListOf<String>()
212-
solutionSecurity.accessControlList.forEach {
213-
if (!accessControls.contains(it.id)) {
214-
accessControls.add(it.id)
215-
} else {
216-
throw IllegalArgumentException("User $it is referenced multiple times in the security")
217-
}
218-
}
219-
}
220206

221-
return solutionRepository.save(
207+
val createdSolution =
222208
solution.copy(
223209
id = idGenerator.generate("solution", prependPrefix = "sol-"),
224210
organizationId = organizationId,
225-
ownerId = getCurrentAuthenticatedUserName(csmPlatformProperties),
226-
security = solutionSecurity))
211+
ownerId = getCurrentAuthenticatedUserName(csmPlatformProperties))
212+
createdSolution.setRbac(csmRbac.initSecurity(solution.getRbac()))
213+
214+
return solutionRepository.save(createdSolution)
227215
}
228216

229217
override fun deleteSolution(organizationId: String, solutionId: String) {
@@ -520,12 +508,6 @@ fun Solution.getRbac(): RbacSecurity {
520508
?: mutableListOf())
521509
}
522510

523-
private fun initSecurity(userId: String): SolutionSecurity {
524-
return SolutionSecurity(
525-
default = ROLE_NONE,
526-
accessControlList = mutableListOf(SolutionAccessControl(userId, ROLE_ADMIN)))
527-
}
528-
529511
fun Solution.setRbac(rbacSecurity: RbacSecurity) {
530512
this.security =
531513
SolutionSecurity(

0 commit comments

Comments
 (0)