Skip to content

Commit 2500df0

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

File tree

7 files changed

+44
-133
lines changed

7 files changed

+44
-133
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
@@ -118,8 +118,10 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
118118

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

130132
@Test
131133
fun `findAllOrganizations with correct values and no RBAC for current user`() {
132-
134+
runAsDifferentOrganizationUser()
133135
val numberOfOrganizationCreated =
134136
createOrganizationsWithAllCombinationOfRole(OTHER_TEST_USER_ID)
137+
138+
runAsOrganizationUser()
135139
// This number represents the amount of Organization that test.user can read regarding RBAC
136140
// We have 36 combinations per user in batchOrganizationCreationWithRBAC
137141
// securityRole does not refer to test.user
@@ -222,7 +226,8 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
222226
OrganizationSecurity(
223227
default = ROLE_USER,
224228
mutableListOf(
225-
OrganizationAccessControl(id = OTHER_TEST_USER_ID, role = ROLE_NONE))),
229+
OrganizationAccessControl(id = OTHER_TEST_USER_ID, role = ROLE_NONE),
230+
OrganizationAccessControl(id = TEST_USER_ID, role = ROLE_ADMIN))),
226231
organizationRegistered.security)
227232
assertEquals(name, organizationRegistered.name)
228233
assertTrue(organizationRegistered.id!!.startsWith("o-"))
@@ -252,7 +257,8 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
252257
assertThrows<CsmAccessForbiddenException> {
253258
val name = "o-connector-test-1"
254259
val organizationToRegister =
255-
createTestOrganizationWithSimpleSecurity(name, OTHER_TEST_USER_ID, ROLE_USER, ROLE_NONE)
260+
createTestOrganizationWithSimpleSecurity(
261+
name, OTHER_TEST_USER_ID, ROLE_USER, ROLE_ADMIN)
256262
val organizationRegistered =
257263
organizationApiService.registerOrganization(organizationToRegister)
258264
organizationApiService.unregisterOrganization(organizationRegistered.id!!)
@@ -1011,7 +1017,7 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
10111017
runAsOrganizationUser()
10121018
val orgaUsers =
10131019
organizationApiService.getOrganizationSecurityUsers(organizationRegistered.id!!)
1014-
assertEquals(listOf(TEST_USER_ID), orgaUsers)
1020+
assertEquals(listOf(TEST_USER_ID, OTHER_TEST_USER_ID), orgaUsers)
10151021
}
10161022

10171023
@Test
@@ -1161,7 +1167,8 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
11611167
OrganizationSecurity(
11621168
default = ROLE_USER,
11631169
mutableListOf(
1164-
OrganizationAccessControl(id = OTHER_TEST_USER_ID, role = ROLE_NONE))),
1170+
OrganizationAccessControl(id = OTHER_TEST_USER_ID, role = ROLE_NONE),
1171+
OrganizationAccessControl(id = TEST_ADMIN_USER_ID, role = ROLE_ADMIN))),
11651172
organizationRegistered.security)
11661173
assertEquals(name, organizationRegistered.name)
11671174
assertTrue(organizationRegistered.id!!.startsWith("o-"))
@@ -2027,7 +2034,7 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
20272034
runAsPlatformAdmin()
20282035
val orgaUsers =
20292036
organizationApiService.getOrganizationSecurityUsers(organizationRegistered.id!!)
2030-
assertEquals(listOf(TEST_USER_ID), orgaUsers)
2037+
assertEquals(listOf(TEST_USER_ID, OTHER_TEST_USER_ID), orgaUsers)
20312038
}
20322039

20332040
@Test
@@ -2040,7 +2047,7 @@ class OrganizationServiceIntegrationTest : CsmRedisTestBase() {
20402047
runAsPlatformAdmin()
20412048
val orgaUsers =
20422049
organizationApiService.getOrganizationSecurityUsers(organizationRegistered.id!!)
2043-
assertEquals(listOf(TEST_USER_ID), orgaUsers)
2050+
assertEquals(listOf(TEST_USER_ID, OTHER_TEST_USER_ID), orgaUsers)
20442051
}
20452052

20462053
@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
@@ -77,33 +76,19 @@ class OrganizationServiceImpl(
7776
}
7877

7978
override fun registerOrganization(organization: Organization): Organization {
80-
logger.trace("Registering organization : {}", organization)
79+
logger.trace("Registering organization: {}", organization)
8180

8281
if (organization.name.isNullOrBlank()) {
8382
throw IllegalArgumentException("Organization name must not be null or blank")
8483
}
8584

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

10994
override fun unregisterOrganization(organizationId: String) {
@@ -242,12 +227,6 @@ class OrganizationServiceImpl(
242227
requiredPermissions.forEach { csmRbac.verify(organization.getRbac(), it) }
243228
return organization
244229
}
245-
246-
private fun initSecurity(userId: String): OrganizationSecurity {
247-
return OrganizationSecurity(
248-
default = ROLE_NONE,
249-
accessControlList = mutableListOf(OrganizationAccessControl(userId, ROLE_ADMIN)))
250-
}
251230
}
252231

253232
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
@@ -37,12 +37,7 @@ internal class RunnerApiServiceImpl(
3737
.inWorkspace(workspaceId)
3838
.userHasPermissionOnWorkspace(PERMISSION_CREATE_CHILDREN)
3939
val runnerInstance =
40-
runnerService
41-
.getNewInstance()
42-
.setValueFrom(runner)
43-
.initSecurity()
44-
.initParameters()
45-
.setSecurityFrom(runner)
40+
runnerService.getNewInstance().setValueFrom(runner).initSecurity(runner).initParameters()
4641

4742
return runnerService.saveInstance(runnerInstance)
4843
}

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
@@ -192,21 +191,13 @@ class RunnerService(
192191
}
193192
}
194193

195-
fun setSecurityFrom(runner: Runner): RunnerInstance = apply {
196-
val rbacSecurity = extractRbacSecurity(runner) ?: return@apply
197-
this.setRbacSecurity(rbacSecurity)
198-
}
199-
200194
fun setLastRunId(runInfo: String) {
201195
this.runner.lastRunId = runInfo
202196
}
203197

204-
fun initSecurity(): RunnerInstance = apply {
205-
val userId = getCurrentAccountIdentifier(csmPlatformProperties)
206-
this.runner.security =
207-
RunnerSecurity(
208-
default = ROLE_NONE,
209-
accessControlList = mutableListOf(RunnerAccessControl(userId, ROLE_ADMIN)))
198+
fun initSecurity(runner: Runner): RunnerInstance = apply {
199+
val rbacSecurity = csmRbac.initSecurity(extractRbacSecurity(runner))
200+
setRbacSecurity(rbacSecurity)
210201
}
211202

212203
fun initParameters(): RunnerInstance = apply {
@@ -270,7 +261,7 @@ class RunnerService(
270261
}
271262

272263
private fun getRbacSecurity(): RbacSecurity {
273-
return extractRbacSecurity(this.runner)!!
264+
return extractRbacSecurity(this.runner)
274265
}
275266

276267
private fun setRbacSecurity(rbacSecurity: RbacSecurity) {
@@ -283,10 +274,7 @@ class RunnerService(
283274
.toMutableList())
284275
}
285276

286-
private fun extractRbacSecurity(runner: Runner): RbacSecurity? {
287-
if (runner.security == null) {
288-
return null
289-
}
277+
private fun extractRbacSecurity(runner: Runner): RbacSecurity {
290278
return RbacSecurity(
291279
runner.id,
292280
runner.security?.default ?: ROLE_NONE,

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

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import com.cosmotech.api.rbac.PERMISSION_DELETE
1313
import com.cosmotech.api.rbac.PERMISSION_READ_SECURITY
1414
import com.cosmotech.api.rbac.PERMISSION_WRITE
1515
import com.cosmotech.api.rbac.PERMISSION_WRITE_SECURITY
16-
import com.cosmotech.api.rbac.ROLE_ADMIN
1716
import com.cosmotech.api.rbac.ROLE_NONE
1817
import com.cosmotech.api.rbac.model.RbacAccessControl
1918
import com.cosmotech.api.rbac.model.RbacSecurity
@@ -191,27 +190,15 @@ class SolutionServiceImpl(
191190

192191
override fun createSolution(organizationId: String, solution: Solution): Solution {
193192
organizationApiService.getVerifiedOrganization(organizationId, PERMISSION_CREATE_CHILDREN)
194-
var solutionSecurity = solution.security
195-
if (solutionSecurity == null) {
196-
solutionSecurity = initSecurity(getCurrentAccountIdentifier(this.csmPlatformProperties))
197-
} else {
198-
val accessControls = mutableListOf<String>()
199-
solutionSecurity.accessControlList.forEach {
200-
if (!accessControls.contains(it.id)) {
201-
accessControls.add(it.id)
202-
} else {
203-
throw IllegalArgumentException("User $it is referenced multiple times in the security")
204-
}
205-
}
206-
}
207193

208-
return solutionRepository.save(
194+
val createdSolution =
209195
solution.copy(
210196
id = idGenerator.generate("solution", prependPrefix = "sol-"),
211197
organizationId = organizationId,
212-
ownerId = getCurrentAuthenticatedUserName(csmPlatformProperties),
213-
security = solutionSecurity,
214-
runTemplates = solution.runTemplates))
198+
ownerId = getCurrentAuthenticatedUserName(csmPlatformProperties))
199+
createdSolution.setRbac(csmRbac.initSecurity(solution.getRbac()))
200+
201+
return solutionRepository.save(createdSolution)
215202
}
216203

217204
override fun deleteSolution(organizationId: String, solutionId: String) {
@@ -412,12 +399,6 @@ fun Solution.getRbac(): RbacSecurity {
412399
?: mutableListOf())
413400
}
414401

415-
private fun initSecurity(userId: String): SolutionSecurity {
416-
return SolutionSecurity(
417-
default = ROLE_NONE,
418-
accessControlList = mutableListOf(SolutionAccessControl(userId, ROLE_ADMIN)))
419-
}
420-
421402
fun Solution.setRbac(rbacSecurity: RbacSecurity) {
422403
this.security =
423404
SolutionSecurity(

workspace/src/main/kotlin/com/cosmotech/workspace/service/WorkspaceServiceImpl.kt

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import com.cosmotech.api.rbac.PERMISSION_READ
1919
import com.cosmotech.api.rbac.PERMISSION_READ_SECURITY
2020
import com.cosmotech.api.rbac.PERMISSION_WRITE
2121
import com.cosmotech.api.rbac.PERMISSION_WRITE_SECURITY
22-
import com.cosmotech.api.rbac.ROLE_ADMIN
2322
import com.cosmotech.api.rbac.ROLE_NONE
2423
import com.cosmotech.api.rbac.getCommonRolesDefinition
2524
import com.cosmotech.api.rbac.getPermissions
@@ -114,26 +113,14 @@ internal class WorkspaceServiceImpl(
114113
// Validate Solution ID
115114
workspace.solution.solutionId?.let { solutionService.findSolutionById(organizationId, it) }
116115

117-
var workspaceSecurity = workspace.security
118-
if (workspaceSecurity == null) {
119-
workspaceSecurity = initSecurity(getCurrentAccountIdentifier(this.csmPlatformProperties))
120-
} else {
121-
val accessControls = mutableListOf<String>()
122-
workspaceSecurity.accessControlList.forEach {
123-
if (!accessControls.contains(it.id)) {
124-
accessControls.add(it.id)
125-
} else {
126-
throw IllegalArgumentException("User $it is referenced multiple times in the security")
127-
}
128-
}
129-
}
130-
131-
return workspaceRepository.save(
116+
val createdWorkspace =
132117
workspace.copy(
133118
id = idGenerator.generate("workspace"),
134119
organizationId = organizationId,
135-
ownerId = getCurrentAuthenticatedUserName(csmPlatformProperties),
136-
security = workspaceSecurity))
120+
ownerId = getCurrentAuthenticatedUserName(csmPlatformProperties))
121+
createdWorkspace.setRbac(csmRbac.initSecurity(workspace.getRbac()))
122+
123+
return workspaceRepository.save(createdWorkspace)
137124
}
138125

139126
override fun deleteAllWorkspaceFiles(organizationId: String, workspaceId: String) {
@@ -531,12 +518,6 @@ internal class WorkspaceServiceImpl(
531518
return workspaceRepository.save(workspace)
532519
}
533520

534-
private fun initSecurity(userId: String): WorkspaceSecurity {
535-
return WorkspaceSecurity(
536-
default = ROLE_NONE,
537-
accessControlList = mutableListOf(WorkspaceAccessControl(userId, ROLE_ADMIN)))
538-
}
539-
540521
private fun sendRemoveWorkspaceFromDatasetEvent(
541522
organizationId: String,
542523
datasetId: String,

0 commit comments

Comments
 (0)