Skip to content

Commit 2de9c43

Browse files
committed
feat: add unified datasource available members endpoint
1 parent 9a52ed3 commit 2de9c43

File tree

4 files changed

+146
-21
lines changed

4 files changed

+146
-21
lines changed

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/datasource/DatasourceApiService.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
package org.lowcoder.api.datasource;
22

3-
import jakarta.annotation.Nullable;
3+
import java.util.List;
4+
import java.util.Set;
5+
46
import org.lowcoder.api.permission.view.CommonPermissionView;
57
import org.lowcoder.domain.datasource.model.Datasource;
68
import org.lowcoder.domain.permission.model.ResourceRole;
79
import org.lowcoder.domain.plugin.client.dto.GetPluginDynamicConfigRequestDTO;
810
import org.lowcoder.sdk.models.DatasourceTestResult;
9-
import org.springframework.web.bind.annotation.RequestParam;
11+
12+
import jakarta.annotation.Nullable;
1013
import reactor.core.publisher.Flux;
1114
import reactor.core.publisher.Mono;
1215

13-
import java.util.List;
14-
import java.util.Set;
15-
1616
public interface DatasourceApiService {
1717
Mono<Datasource> create(Datasource datasource);
1818

@@ -41,4 +41,6 @@ public interface DatasourceApiService {
4141
Mono<Boolean> updatePermission(String permissionId, ResourceRole role);
4242

4343
Mono<Boolean> deletePermission(String permissionId);
44+
45+
Mono<List<Object>> getGroupsOrMembersWithoutPermissions(String datasourceId);
4446
}

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/datasource/DatasourceApiServiceImpl.java

Lines changed: 85 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,31 @@
11
package org.lowcoder.api.datasource;
22

3-
import com.github.f4b6a3.uuid.UuidCreator;
4-
import jakarta.annotation.Nullable;
5-
import lombok.RequiredArgsConstructor;
3+
import static org.lowcoder.domain.permission.model.ResourceAction.MANAGE_DATASOURCES;
4+
import static org.lowcoder.domain.permission.model.ResourceAction.READ_APPLICATIONS;
5+
import static org.lowcoder.domain.permission.model.ResourceAction.USE_DATASOURCES;
6+
import static org.lowcoder.sdk.exception.BizError.NOT_AUTHORIZED;
7+
import static org.lowcoder.sdk.util.ExceptionUtils.deferredError;
8+
9+
import java.util.ArrayList;
10+
import java.util.Collections;
11+
import java.util.HashMap;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.Set;
15+
import java.util.stream.Collectors;
16+
617
import org.apache.commons.collections4.CollectionUtils;
718
import org.apache.commons.lang3.StringUtils;
819
import org.lowcoder.api.application.ApplicationApiService;
920
import org.lowcoder.api.home.SessionUserService;
1021
import org.lowcoder.api.permission.PermissionHelper;
1122
import org.lowcoder.api.permission.view.CommonPermissionView;
1223
import org.lowcoder.api.permission.view.PermissionItemView;
24+
import org.lowcoder.api.usermanagement.GroupApiService;
25+
import org.lowcoder.api.usermanagement.OrgApiService;
1326
import org.lowcoder.api.usermanagement.OrgDevChecker;
27+
import org.lowcoder.api.usermanagement.view.GroupView;
28+
import org.lowcoder.api.usermanagement.view.OrgMemberListView;
1429
import org.lowcoder.domain.application.service.ApplicationService;
1530
import org.lowcoder.domain.datasource.model.Datasource;
1631
import org.lowcoder.domain.datasource.model.DatasourceStatus;
@@ -38,18 +53,13 @@
3853
import org.lowcoder.sdk.models.HasIdAndAuditing;
3954
import org.lowcoder.sdk.models.JsDatasourceConnectionConfig;
4055
import org.springframework.stereotype.Service;
41-
import reactor.core.publisher.Flux;
42-
import reactor.core.publisher.Mono;
4356

44-
import java.util.Collections;
45-
import java.util.List;
46-
import java.util.Map;
47-
import java.util.Set;
48-
import java.util.stream.Collectors;
57+
import com.github.f4b6a3.uuid.UuidCreator;
4958

50-
import static org.lowcoder.domain.permission.model.ResourceAction.*;
51-
import static org.lowcoder.sdk.exception.BizError.NOT_AUTHORIZED;
52-
import static org.lowcoder.sdk.util.ExceptionUtils.deferredError;
59+
import jakarta.annotation.Nullable;
60+
import lombok.RequiredArgsConstructor;
61+
import reactor.core.publisher.Flux;
62+
import reactor.core.publisher.Mono;
5363

5464
@RequiredArgsConstructor
5565
@Service
@@ -71,6 +81,8 @@ public class DatasourceApiServiceImpl implements DatasourceApiService {
7181
private final DatasourcePluginClient datasourcePluginClient;
7282
private final DatasourceRepository datasourceRepository;
7383
private final ApplicationApiService applicationApiService;
84+
private final OrgApiService orgApiService;
85+
private final GroupApiService groupApiService;
7486

7587
@Override
7688
public Mono<Datasource> create(Datasource datasource) {
@@ -267,6 +279,66 @@ public Mono<Boolean> grantPermission(String datasourceId, @Nullable Set<String>
267279
.thenReturn(true);
268280
}
269281

282+
@Override
283+
public Mono<List<Object>> getGroupsOrMembersWithoutPermissions(String datasourceId) {
284+
return datasourceService.getById(datasourceId)
285+
.switchIfEmpty(Mono.error(new ServerException("data source not exist. {}", datasourceId)))
286+
.flatMap(datasource -> {
287+
String orgId = datasource.getOrganizationId();
288+
Mono<List<ResourcePermission>> datasourcePermissions = resourcePermissionService.getByDataSourceId(datasource.getId()).cache();
289+
290+
Mono<List<PermissionItemView>> groupPermissionPairsMono = datasourcePermissions
291+
.flatMap(permissionHelper::getGroupPermissions);
292+
293+
Mono<List<PermissionItemView>> userPermissionPairsMono = datasourcePermissions
294+
.flatMap(permissionHelper::getUserPermissions);
295+
Mono<OrgMemberListView> orgMemberListViewMono = orgApiService.getOrganizationMembers(orgId, 1, 0);
296+
Mono<List<GroupView>> groupsViewMono = groupApiService.getGroups();
297+
298+
return Mono.zip(groupPermissionPairsMono, userPermissionPairsMono, orgMemberListViewMono, groupsViewMono)
299+
.map(tuple -> {
300+
List<PermissionItemView> groupPermissionPairs = tuple.getT1();
301+
List<PermissionItemView> userPermissionPairs = tuple.getT2();
302+
OrgMemberListView orgMemberListViews = tuple.getT3();
303+
List<GroupView> groupListViews = tuple.getT4();
304+
305+
Set<String> groupIdsWithPerm = groupPermissionPairs.stream()
306+
.map(PermissionItemView::getId)
307+
.collect(java.util.stream.Collectors.toSet());
308+
309+
List<java.util.Map<String, Object>> filteredGroups = groupListViews.stream()
310+
.filter(group -> !groupIdsWithPerm.contains(group.getGroupId()))
311+
.map(group -> {
312+
java.util.Map<String, Object> map = new java.util.HashMap<>();
313+
map.put("type", "Group");
314+
map.put("data", group);
315+
return map;
316+
})
317+
.toList();
318+
319+
Set<String> userIdsWithPerm = userPermissionPairs.stream()
320+
.map(PermissionItemView::getId)
321+
.collect(java.util.stream.Collectors.toSet());
322+
323+
List<Map<String, Object>> filteredMembers = orgMemberListViews.getMembers().stream()
324+
.filter(member -> !userIdsWithPerm.contains(member.getUserId()))
325+
.map(member -> {
326+
Map<String, Object> map = new HashMap<>();
327+
map.put("type", "User");
328+
map.put("data", member);
329+
return map;
330+
})
331+
.toList();
332+
333+
List<Object> result = new ArrayList<>();
334+
result.addAll(filteredGroups);
335+
result.addAll(filteredMembers);
336+
return result;
337+
});
338+
});
339+
}
340+
341+
270342
@Override
271343
public Mono<Boolean> updatePermission(String permissionId, ResourceRole role) {
272344
return checkBeforePermissionDeleteOrUpdate(permissionId)

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/datasource/DatasourceController.java

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import org.lowcoder.api.framework.view.PageResponseView;
1111
import org.lowcoder.api.framework.view.ResponseView;
1212
import org.lowcoder.api.permission.view.CommonPermissionView;
13+
import org.lowcoder.api.usermanagement.view.GroupView;
14+
import org.lowcoder.api.usermanagement.view.OrgMemberListView;
1315
import org.lowcoder.api.usermanagement.view.UpdateGroupRequest;
1416
import org.lowcoder.api.util.BusinessEventPublisher;
1517
import org.lowcoder.api.util.GidService;
@@ -26,17 +28,17 @@
2628
import org.springframework.web.bind.annotation.RequestBody;
2729
import org.springframework.web.bind.annotation.RequestParam;
2830
import org.springframework.web.bind.annotation.RestController;
31+
import reactor.core.publisher.Flux;
2932
import reactor.core.publisher.Mono;
3033

31-
import java.util.Collections;
32-
import java.util.List;
33-
import java.util.Locale;
34+
import java.util.*;
3435

3536
import static org.lowcoder.api.util.Pagination.fluxToPageResponseView;
3637
import static org.lowcoder.plugin.api.event.LowcoderEvent.EventType.*;
3738
import static org.lowcoder.sdk.exception.BizError.INVALID_PARAMETER;
3839
import static org.lowcoder.sdk.util.ExceptionUtils.ofError;
3940
import static org.lowcoder.sdk.util.LocaleUtils.getLocale;
41+
import static reactor.core.publisher.Flux.fromIterable;
4042

4143
@RequiredArgsConstructor
4244
@RestController
@@ -227,4 +229,38 @@ public Mono<ResponseView<Object>> info(@RequestParam(required = false) String da
227229
Mono.just(ResponseView.success(datasourceApiService.info(objectId))));
228230
}
229231

232+
@Override
233+
public Mono<PageResponseView<?>> getGroupsOrMembersWithoutPermissions(
234+
@PathVariable String datasourceId,
235+
@RequestParam(required = false) String search,
236+
@RequestParam(required = false, defaultValue = "1") Integer pageNum,
237+
@RequestParam(required = false, defaultValue = "1000") Integer pageSize) {
238+
239+
return gidService.convertDatasourceIdToObjectId(datasourceId).flatMap(dsId -> {
240+
var flx = datasourceApiService.getGroupsOrMembersWithoutPermissions(dsId)
241+
.flatMapMany(Flux::fromIterable)
242+
.filter(item -> {
243+
if (search == null || search.isBlank()) return true;
244+
if (!(item instanceof Map map)) return false;
245+
Object type = map.get("type");
246+
Object data = map.get("data");
247+
if ("Group".equals(type) && data instanceof GroupView group) {
248+
return group.getGroupName() != null && group.getGroupName().toLowerCase().contains(search.toLowerCase());
249+
}
250+
if ("User".equals(type) && data instanceof OrgMemberListView.OrgMemberView user) {
251+
return user.getName() != null && user.getName().toLowerCase().contains(search.toLowerCase());
252+
}
253+
return false;
254+
})
255+
.cache();
256+
var countMono = flx.count();
257+
var flux1 = flx.skip((long) (pageNum - 1) * pageSize);
258+
if (pageSize > 0) flux1 = flux1.take(pageSize);
259+
return flux1.collectList()
260+
.zipWith(countMono)
261+
.map(tuple -> PageResponseView.success(tuple.getT1(), pageNum, pageSize, Math.toIntExact(tuple.getT2())));
262+
});
263+
}
264+
265+
230266
}

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/datasource/DatasourceEndpoints.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,21 @@ public Mono<ResponseView<Boolean>> updatePermission(@PathVariable("permissionId"
190190
@GetMapping("/info")
191191
public Mono<ResponseView<Object>> info(@RequestParam(required = false) String datasourceId);
192192

193+
194+
@Operation(
195+
tags = TAG_DATASOURCE_PERMISSIONS,
196+
operationId = "listGroupsOrMembersWithoutPermissionsForDatasource",
197+
summary = "Get groups or members without permissions for datasource",
198+
description = "Retrieve the groups or members of a specific datasource identified by its ID that do not have permissions."
199+
)
200+
@GetMapping("/{datasourceId}/available")
201+
public Mono<PageResponseView<?>> getGroupsOrMembersWithoutPermissions(
202+
@PathVariable String datasourceId,
203+
@RequestParam(required = false) String search,
204+
@RequestParam(required = false, defaultValue = "1") Integer pageNum,
205+
@RequestParam(required = false, defaultValue = "1000") Integer pageSize
206+
);
207+
193208
public record BatchAddPermissionRequest(String role, Set<String> userIds, Set<String> groupIds) {
194209
}
195210

0 commit comments

Comments
 (0)