@@ -67,6 +67,8 @@ import org.eclipse.apoapsis.ortserver.api.v1.model.VulnerabilityForRunsFilters
6767import org.eclipse.apoapsis.ortserver.api.v1.model.VulnerabilityRating
6868import org.eclipse.apoapsis.ortserver.components.authorization.api.OrganizationRole as ApiOrganizationRole
6969import org.eclipse.apoapsis.ortserver.components.authorization.rights.OrganizationRole
70+ import org.eclipse.apoapsis.ortserver.components.authorization.rights.ProductRole
71+ import org.eclipse.apoapsis.ortserver.components.authorization.rights.RepositoryRole
7072import org.eclipse.apoapsis.ortserver.components.authorization.routes.mapToModel
7173import org.eclipse.apoapsis.ortserver.components.authorization.service.AuthorizationService
7274import org.eclipse.apoapsis.ortserver.components.authorization.service.DbAuthorizationService
@@ -75,6 +77,8 @@ import org.eclipse.apoapsis.ortserver.core.TEST_USER
7577import org.eclipse.apoapsis.ortserver.model.CompoundHierarchyId
7678import org.eclipse.apoapsis.ortserver.model.JobStatus
7779import org.eclipse.apoapsis.ortserver.model.OrganizationId
80+ import org.eclipse.apoapsis.ortserver.model.ProductId
81+ import org.eclipse.apoapsis.ortserver.model.RepositoryId
7882import org.eclipse.apoapsis.ortserver.model.RepositoryType
7983import org.eclipse.apoapsis.ortserver.model.Severity
8084import org.eclipse.apoapsis.ortserver.model.runs.Identifier
@@ -605,6 +609,77 @@ class OrganizationsRouteIntegrationTest : AbstractIntegrationTest({
605609 }
606610 }
607611
612+ " return only products for which the user has ProductPermission.READ" {
613+ integrationTestApplication {
614+ val createdOrganization = createOrganization()
615+ val orgId = createdOrganization.id
616+ val otherOrg = createOrganization("otherOrg")
617+
618+ val name1 = " name1"
619+ val name2 = " name2"
620+ val description = " description"
621+
622+ val createdProduct1 =
623+ organizationService.createProduct(name = name1, description = description, organizationId = orgId)
624+ val createdProduct2 =
625+ organizationService.createProduct(name = name2, description = description, organizationId = orgId)
626+ organizationService.createProduct(name = "name3", description = description, organizationId = orgId)
627+ val createdRepo = productService.createRepository(
628+ RepositoryType .GIT ,
629+ "https://example.com/repo.git",
630+ createdProduct2.id,
631+ null
632+ )
633+ val productInOtherOrg = organizationService.createProduct(
634+ name = "otherOrgProduct",
635+ description = description,
636+ organizationId = otherOrg.id
637+ )
638+
639+ authorizationService.assignRole(
640+ TEST_USER .username.value,
641+ ProductRole .READER ,
642+ CompoundHierarchyId .forProduct(
643+ OrganizationId (createdOrganization.id),
644+ ProductId (createdProduct1.id)
645+ )
646+ )
647+ authorizationService.assignRole(
648+ TEST_USER .username.value,
649+ ProductRole .READER ,
650+ CompoundHierarchyId .forProduct(
651+ OrganizationId (otherOrg.id),
652+ ProductId (productInOtherOrg.id)
653+ )
654+ )
655+ authorizationService.assignRole(
656+ TEST_USER .username.value,
657+ RepositoryRole .WRITER ,
658+ CompoundHierarchyId .forRepository(
659+ OrganizationId (createdOrganization.id),
660+ ProductId (createdProduct2.id),
661+ RepositoryId (createdRepo.id)
662+ )
663+ )
664+
665+ val response = testUserClient.get("/api/v1/organizations/$orgId/products")
666+
667+ response shouldHaveStatus HttpStatusCode .OK
668+ response shouldHaveBody PagedResponse (
669+ listOf(
670+ Product (createdProduct1.id, orgId, name1, description),
671+ Product (createdProduct2.id, orgId, name2, description)
672+ ),
673+ PagingData (
674+ limit = DEFAULT_LIMIT ,
675+ offset = 0,
676+ totalCount = 2,
677+ sortProperties = listOf(SortProperty ("name", SortDirection .ASCENDING ))
678+ )
679+ )
680+ }
681+ }
682+
608683 " support query parameters" {
609684 integrationTestApplication {
610685 val orgId = createOrganization().id
0 commit comments