Skip to content

Commit 3ac9b1d

Browse files
fix: respect env scope when fetching user groups with envId
1 parent bdb8b9d commit 3ac9b1d

File tree

4 files changed

+180
-2
lines changed

4 files changed

+180
-2
lines changed

gravitee-apim-rest-api/gravitee-apim-rest-api-management/gravitee-apim-rest-api-management-rest/src/main/java/io/gravitee/rest/api/management/rest/resource/organization/UserResource.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
import java.util.HashMap;
4848
import java.util.List;
4949
import java.util.Set;
50+
import lombok.extern.slf4j.XSlf4j;
51+
import org.slf4j.Logger;
52+
import org.slf4j.LoggerFactory;
5053

5154
/**
5255
* Defines the REST resources to manage Users.
@@ -60,6 +63,8 @@
6063
@Tag(name = "Users")
6164
public class UserResource extends AbstractResource {
6265

66+
private static final Logger logger = LoggerFactory.getLogger(UserResource.class);
67+
6368
@Context
6469
private ResourceContext resourceContext;
6570

@@ -123,10 +128,10 @@ public Response deleteUser() {
123128
public List<UserGroupEntity> getUserGroups() {
124129
// Check that user belongs to current organization
125130
userService.findById(GraviteeContext.getExecutionContext(), userId);
126-
131+
String currentEnvironmentId = GraviteeContext.getCurrentEnvironment();
127132
List<UserGroupEntity> groups = new ArrayList<>();
128133
groupService
129-
.findByUser(userId)
134+
.findByUserAndEnvironment(userId, currentEnvironmentId)
130135
.forEach(groupEntity -> {
131136
UserGroupEntity userGroupEntity = new UserGroupEntity();
132137
userGroupEntity.setId(groupEntity.getId());
@@ -144,6 +149,13 @@ public List<UserGroupEntity> getUserGroups() {
144149
groups.add(userGroupEntity);
145150
});
146151

152+
logger.debug(
153+
"getUserGroups returning {} groups for userId='{}': {}",
154+
groups.size(),
155+
userId,
156+
groups.stream().map(UserGroupEntity::getName).toList()
157+
);
158+
147159
return groups;
148160
}
149161

gravitee-apim-rest-api/gravitee-apim-rest-api-service/src/main/java/io/gravitee/rest/api/service/GroupService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public interface GroupService {
4949
List<GroupEntity> findByName(final String environmentId, String name);
5050

5151
Set<GroupEntity> findByUser(String username);
52+
Set<GroupEntity> findByUserAndEnvironment(String username, String environmentId);
5253
List<ApiEntity> getApis(final String environmentId, String groupId);
5354
List<ApplicationEntity> getApplications(String groupId);
5455
int getNumberOfMembers(ExecutionContext executionContext, String groupId);

gravitee-apim-rest-api/gravitee-apim-rest-api-service/src/main/java/io/gravitee/rest/api/service/impl/GroupServiceImpl.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,48 @@ public Set<GroupEntity> findByUser(String user) {
907907
}
908908
}
909909

910+
@Override
911+
public Set<GroupEntity> findByUserAndEnvironment(String user, String environmentId) {
912+
logger.debug("Finding groups for user '{}' in environment '{}'", user, environmentId);
913+
914+
Set<String> userGroups = membershipService
915+
.getMembershipsByMemberAndReference(MembershipMemberType.USER, user, MembershipReferenceType.GROUP)
916+
.stream()
917+
.map(MembershipEntity::getReferenceId)
918+
.collect(Collectors.toSet());
919+
920+
try {
921+
Set<Group> allGroups = groupRepository.findByIds(userGroups);
922+
Set<GroupEntity> filteredGroups = allGroups
923+
.stream()
924+
.filter(group -> {
925+
boolean matches = environmentId == null || environmentId.equals(group.getEnvironmentId());
926+
if (!matches) {
927+
logger.debug(
928+
"Filtering out group '{}' (id: {}, env: {}) - does not match environment '{}'",
929+
group.getName(),
930+
group.getId(),
931+
group.getEnvironmentId(),
932+
environmentId
933+
);
934+
}
935+
return matches;
936+
})
937+
.map(this::map)
938+
.collect(Collectors.toSet());
939+
940+
logger.debug(
941+
"After filtering by environment '{}': {} groups remain: {}",
942+
environmentId,
943+
filteredGroups.size(),
944+
filteredGroups.stream().map(GroupEntity::getName).collect(Collectors.toList())
945+
);
946+
return filteredGroups;
947+
} catch (TechnicalException ex) {
948+
throw new TechnicalManagementException("An error occurs while trying to find user groups for environment " + environmentId, ex);
949+
}
950+
}
951+
910952
@Override
911953
public List<ApiEntity> getApis(final String environmentId, String groupId) {
912954
return apiRepository
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright © 2015 The Gravitee team (http://gravitee.io)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.gravitee.rest.api.service.impl;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
import static org.mockito.Mockito.when;
20+
21+
import io.gravitee.repository.exceptions.TechnicalException;
22+
import io.gravitee.repository.management.api.GroupRepository;
23+
import io.gravitee.repository.management.model.Group;
24+
import io.gravitee.rest.api.model.GroupEntity;
25+
import io.gravitee.rest.api.model.MembershipEntity;
26+
import io.gravitee.rest.api.model.MembershipMemberType;
27+
import io.gravitee.rest.api.model.MembershipReferenceType;
28+
import io.gravitee.rest.api.service.MembershipService;
29+
import java.util.Arrays;
30+
import java.util.Collections;
31+
import java.util.HashSet;
32+
import java.util.Set;
33+
import org.junit.Test;
34+
import org.junit.runner.RunWith;
35+
import org.mockito.InjectMocks;
36+
import org.mockito.Mock;
37+
import org.mockito.junit.MockitoJUnitRunner;
38+
39+
@RunWith(MockitoJUnitRunner.class)
40+
public class GroupService_FindByUserAndEnvironmentTest {
41+
42+
@InjectMocks
43+
private final GroupServiceImpl groupService = new GroupServiceImpl();
44+
45+
@Mock
46+
private GroupRepository groupRepository;
47+
48+
@Mock
49+
private MembershipService membershipService;
50+
51+
@Test
52+
public void shouldReturnGroupsForUserInEnvironment() throws TechnicalException {
53+
String userId = "user1";
54+
String envId = "env1";
55+
Group group1 = Group.builder().id("g1").environmentId(envId).name("Group1").build();
56+
Group group2 = Group.builder().id("g2").environmentId("env2").name("Group2").build();
57+
Group group3 = Group.builder().id("g3").environmentId(envId).name("Group3").build();
58+
Set<String> userGroups = new HashSet<>(Arrays.asList("g1", "g2", "g3"));
59+
when(
60+
membershipService.getMembershipsByMemberAndReference(MembershipMemberType.USER, userId, MembershipReferenceType.GROUP)
61+
).thenReturn(
62+
new HashSet<>(
63+
Arrays.asList(
64+
MembershipEntity.builder().id("m1").referenceId("g1").build(),
65+
MembershipEntity.builder().id("m2").referenceId("g2").build(),
66+
MembershipEntity.builder().id("m3").referenceId("g3").build()
67+
)
68+
)
69+
);
70+
when(groupRepository.findByIds(userGroups)).thenReturn(Set.of(group1, group2, group3));
71+
Set<GroupEntity> result = groupService.findByUserAndEnvironment(userId, envId);
72+
assertThat(result).hasSize(2);
73+
assertThat(result.stream().map(GroupEntity::getName)).containsExactlyInAnyOrder("Group1", "Group3");
74+
}
75+
76+
@Test
77+
public void shouldReturnEmptyForUserWithNoGroupsInEnv() throws TechnicalException {
78+
String userId = "user2";
79+
String envId = "env1";
80+
Group group1 = Group.builder().id("g1").environmentId("env2").name("Group2").build();
81+
Set<String> userGroups = Collections.singleton("g1");
82+
when(
83+
membershipService.getMembershipsByMemberAndReference(MembershipMemberType.USER, userId, MembershipReferenceType.GROUP)
84+
).thenReturn(new HashSet<>(Collections.singletonList(MembershipEntity.builder().id("m4").referenceId("g1").build())));
85+
when(groupRepository.findByIds(userGroups)).thenReturn(Set.of(group1));
86+
Set<GroupEntity> result = groupService.findByUserAndEnvironment(userId, envId);
87+
assertThat(result).isEmpty();
88+
}
89+
90+
@Test
91+
public void shouldReturnEmptyForNonExistentUserOrEnv() throws TechnicalException {
92+
String userId = "nouser";
93+
String envId = "noenv";
94+
when(
95+
membershipService.getMembershipsByMemberAndReference(MembershipMemberType.USER, userId, MembershipReferenceType.GROUP)
96+
).thenReturn(new HashSet<>());
97+
when(groupRepository.findByIds(Collections.emptySet())).thenReturn(Set.of());
98+
Set<GroupEntity> result = groupService.findByUserAndEnvironment(userId, envId);
99+
assertThat(result).isEmpty();
100+
}
101+
102+
@Test
103+
public void shouldReturnAllGroupsIfEnvIdIsNull() throws TechnicalException {
104+
String userId = "user3";
105+
Group group1 = Group.builder().id("g1").environmentId("env1").name("Group1").build();
106+
Group group2 = Group.builder().id("g2").environmentId("env2").name("Group2").build();
107+
Set<String> userGroups = new HashSet<>(Arrays.asList("g1", "g2"));
108+
when(
109+
membershipService.getMembershipsByMemberAndReference(MembershipMemberType.USER, userId, MembershipReferenceType.GROUP)
110+
).thenReturn(
111+
new HashSet<>(
112+
Arrays.asList(
113+
MembershipEntity.builder().id("m5").referenceId("g1").build(),
114+
MembershipEntity.builder().id("m6").referenceId("g2").build()
115+
)
116+
)
117+
);
118+
when(groupRepository.findByIds(userGroups)).thenReturn(Set.of(group1, group2));
119+
Set<GroupEntity> result = groupService.findByUserAndEnvironment(userId, null);
120+
assertThat(result).hasSize(2);
121+
assertThat(result.stream().map(GroupEntity::getName)).containsExactlyInAnyOrder("Group1", "Group2");
122+
}
123+
}

0 commit comments

Comments
 (0)