Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 697c308

Browse files
Merge pull request #677 from lowcoder-org/app-public-to-marketplace-feature
Make App Public To Marketplace Feature
2 parents 16e8b29 + ff6b08f commit 697c308

File tree

16 files changed

+235
-12
lines changed

16 files changed

+235
-12
lines changed

‎server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/model/Application.java‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public class Application extends HasIdAndAuditing {
3939
private final Map<String, Object> publishedApplicationDSL;
4040

4141
private final Boolean publicToAll;
42+
private final Boolean publicToMarketplace;
43+
4244
private Map<String, Object> editingApplicationDSL;
4345

4446
@Transient
@@ -75,13 +77,15 @@ public Application(@JsonProperty("orgId") String organizationId,
7577
@JsonProperty("applicationStatus") ApplicationStatus applicationStatus,
7678
@JsonProperty("publishedApplicationDSL") Map<String, Object> publishedApplicationDSL,
7779
@JsonProperty("publicToAll") Boolean publicToAll,
80+
@JsonProperty("publicToMarketplace") Boolean publicToMarketplace,
7881
@JsonProperty("editingApplicationDSL") Map<String, Object> editingApplicationDSL) {
7982
this.organizationId = organizationId;
8083
this.name = name;
8184
this.applicationType = applicationType;
8285
this.applicationStatus = applicationStatus;
8386
this.publishedApplicationDSL = publishedApplicationDSL;
8487
this.publicToAll = publicToAll;
88+
this.publicToMarketplace = publicToMarketplace;
8589
this.editingApplicationDSL = editingApplicationDSL;
8690
}
8791

@@ -105,6 +109,10 @@ public boolean isPublicToAll() {
105109
return BooleanUtils.toBooleanDefaultIfNull(publicToAll, false);
106110
}
107111

112+
public boolean isPublicToMarketplace() {
113+
return BooleanUtils.toBooleanDefaultIfNull(publicToMarketplace, false);
114+
}
115+
108116
public ApplicationQuery getQueryByViewModeAndQueryId(boolean isViewMode, String queryId) {
109117
return (isViewMode ? getLiveQueries() : getEditingQueries())
110118
.stream()

‎server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public interface ApplicationRepository extends ReactiveMongoRepository<Applicati
3535
Flux<Application> findByIdIn(List<String> ids);
3636

3737
@Query(fields = "{_id : 1}")
38-
Flux<Application> findByPublicToAllIsTrueAndIdIn(Collection<String> ids);
38+
Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceIsAndIdIn(Boolean publicToMarketplace, Collection<String> ids);
39+
40+
Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceIsTrue();
3941

4042
}

‎server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ public Flux<Application> findByOrganizationIdWithoutDsl(String organizationId) {
103103
return repository.findByOrganizationId(organizationId);
104104
}
105105

106+
public Flux<Application> findAllMarketplaceApps() {
107+
return repository.findByPublicToAllIsTrueAndPublicToMarketplaceIsTrue();
108+
}
109+
106110
public Mono<Long> countByOrganizationId(String orgId, ApplicationStatus applicationStatus) {
107111
return repository.countByOrganizationIdAndApplicationStatus(orgId, applicationStatus);
108112
}
@@ -147,11 +151,19 @@ public Mono<Boolean> setApplicationPublicToAll(String applicationId, boolean pub
147151
return mongoUpsertHelper.updateById(application, applicationId);
148152
}
149153

154+
public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, boolean publicToMarketplace) {
155+
Application application = Application.builder()
156+
.publicToMarketplace(publicToMarketplace)
157+
.build();
158+
return mongoUpsertHelper.updateById(application, applicationId);
159+
}
160+
150161
@NonEmptyMono
151162
@SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
152-
public Mono<Set<String>> getPublicApplicationIds(Collection<String> applicationIds) {
153-
return repository.findByPublicToAllIsTrueAndIdIn(applicationIds)
163+
public Mono<Set<String>> getPublicApplicationIds(Collection<String> applicationIds, BooleanisAnonymous) {
164+
return repository.findByPublicToAllIsTrueAndPublicToMarketplaceIsAndIdIn(!isAnonymous, applicationIds)
154165
.map(HasIdAndAuditing::getId)
155166
.collect(Collectors.toSet());
167+
156168
}
157169
}

‎server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/model/ResourceAction.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public enum ResourceAction {
2424
EDIT_APPLICATIONS(ResourceRole.EDITOR, ResourceType.APPLICATION),
2525

2626
SET_APPLICATIONS_PUBLIC(ResourceRole.EDITOR, ResourceType.APPLICATION),
27+
SET_APPLICATIONS_PUBLIC_TO_MARKETPLACE(ResourceRole.EDITOR, ResourceType.APPLICATION),
2728

2829
// datasource action
2930
MANAGE_DATASOURCES(ResourceRole.OWNER, ResourceType.DATASOURCE),

‎server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ApplicationPermissionHandler.java‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,22 @@ protected Mono<Map<String, List<ResourcePermission>>> getAnonymousUserPermission
4646
}
4747

4848
Set<String> applicationIds = newHashSet(resourceIds);
49-
return Mono.zip(applicationService.getPublicApplicationIds(applicationIds),
49+
return Mono.zip(applicationService.getPublicApplicationIds(applicationIds, Boolean.TRUE),
50+
templateSolution.getTemplateApplicationIds(applicationIds))
51+
.map(tuple -> {
52+
Set<String> publicAppIds = tuple.getT1();
53+
Set<String> templateAppIds = tuple.getT2();
54+
return collectMap(union(publicAppIds, templateAppIds), identity(), this::getAnonymousUserPermission);
55+
});
56+
}
57+
58+
// This is for PTM apps that are public but only available to logged-in users
59+
@Override
60+
protected Mono<Map<String, List<ResourcePermission>>> getNonAnonymousUserPublicResourcePermissions
61+
(Collection<String> resourceIds, ResourceAction resourceAction) {
62+
63+
Set<String> applicationIds = newHashSet(resourceIds);
64+
return Mono.zip(applicationService.getPublicApplicationIds(applicationIds, Boolean.FALSE),
5065
templateSolution.getTemplateApplicationIds(applicationIds))
5166
.map(tuple -> {
5267
Set<String> publicAppIds = tuple.getT1();

‎server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/DatasourcePermissionHandler.java‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.lowcoder.domain.permission.service;
22

33
import static org.lowcoder.domain.permission.model.ResourceHolder.USER;
4-
import static org.lowcoder.sdk.constants.Authentication.ANONYMOUS_USER_ID;
54

65
import java.util.Collection;
76
import java.util.Collections;
@@ -39,6 +38,11 @@ protected Mono<Map<String, List<ResourcePermission>>> getAnonymousUserPermission
3938
return Mono.just(Collections.emptyMap());
4039
}
4140

41+
@Override
42+
protected Mono<Map<String, List<ResourcePermission>>> getNonAnonymousUserPublicResourcePermissions(Collection<String> resourceIds, ResourceAction resourceAction) {
43+
return Mono.just(Collections.emptyMap());
44+
}
45+
4246
@Override
4347
protected Mono<String> getOrgId(String resourceId) {
4448
return datasourceService.getById(resourceId)

‎server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionHandler.java‎

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,16 @@ public Mono<UserPermissionOnResourceStatus> checkUserPermissionStatusOnResource(
9494
return publicResourcePermissionMono;
9595
}
9696

97+
Mono<UserPermissionOnResourceStatus> nonAnonymousPublicResourcePermissionMono = getNonAnonymousUserPublicResourcePermissions(singletonList(resourceId), resourceAction)
98+
.map(it -> it.getOrDefault(resourceId, emptyList()))
99+
.map(it -> {
100+
if (!it.isEmpty()) {
101+
return UserPermissionOnResourceStatus.success(it.get(0));
102+
}
103+
return isAnonymousUser(userId) ? UserPermissionOnResourceStatus.anonymousUser() : UserPermissionOnResourceStatus.notInOrg();
104+
});
105+
106+
97107
Mono<UserPermissionOnResourceStatus> orgUserPermissionMono = getOrgId(resourceId)
98108
.flatMap(orgId -> orgMemberService.getOrgMember(orgId, userId))
99109
.flatMap(orgMember -> {
@@ -107,13 +117,17 @@ public Mono<UserPermissionOnResourceStatus> checkUserPermissionStatusOnResource(
107117
})
108118
.defaultIfEmpty(UserPermissionOnResourceStatus.notInOrg());
109119

110-
return Mono.zip(publicResourcePermissionMono, orgUserPermissionMono)
120+
return Mono.zip(publicResourcePermissionMono, nonAnonymousPublicResourcePermissionMono, orgUserPermissionMono)
111121
.map(tuple -> {
112122
UserPermissionOnResourceStatus publicResourcePermission = tuple.getT1();
113-
UserPermissionOnResourceStatus orgUserPermission = tuple.getT2();
123+
UserPermissionOnResourceStatus nonAnonymousPublicResourcePermission = tuple.getT2();
124+
UserPermissionOnResourceStatus orgUserPermission = tuple.getT3();
114125
if (orgUserPermission.hasPermission()) {
115126
return orgUserPermission;
116127
}
128+
if(nonAnonymousPublicResourcePermission.hasPermission()) {
129+
return nonAnonymousPublicResourcePermission;
130+
}
117131
if (publicResourcePermission.hasPermission()) {
118132
return publicResourcePermission;
119133
}
@@ -132,6 +146,9 @@ private ResourcePermission getMaxPermission(List<ResourcePermission> permissions
132146
protected abstract Mono<Map<String, List<ResourcePermission>>> getAnonymousUserPermissions(Collection<String> resourceIds,
133147
ResourceAction resourceAction);
134148

149+
protected abstract Mono<Map<String, List<ResourcePermission>>> getNonAnonymousUserPublicResourcePermissions
150+
(Collection<String> resourceIds, ResourceAction resourceAction);
151+
135152
private Mono<Map<String, List<ResourcePermission>>> getAllMatchingPermissions0(String userId, String orgId, ResourceType resourceType,
136153
Collection<String> resourceIds,
137154
ResourceAction resourceAction) {

‎server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionService.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ public Mono<ResourcePermission> checkAndReturnMaxPermission(String userId, Strin
214214
});
215215
}
216216

217-
public Mono<UserPermissionOnResourceStatus> checkUserPermissionStatusOnResource(String userId, String resourceId, ResourceAction resourceAction) {
217+
public Mono<UserPermissionOnResourceStatus> checkUserPermissionStatusOnResource
218+
(String userId, String resourceId, ResourceAction resourceAction) {
218219
ResourceType resourceType = resourceAction.getResourceType();
219220
var resourcePermissionHandler = getResourcePermissionHandler(resourceType);
220221
return resourcePermissionHandler.checkUserPermissionStatusOnResource(userId, resourceId, resourceAction);

‎server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public Mono<ApplicationView> create(CreateApplicationRequest createApplicationRe
141141
createApplicationRequest.applicationType(),
142142
NORMAL,
143143
createApplicationRequest.publishedApplicationDSL(),
144-
false, createApplicationRequest.editingApplicationDSL());
144+
false, false, createApplicationRequest.editingApplicationDSL());
145145

146146
if (StringUtils.isBlank(application.getOrganizationId())) {
147147
return deferredError(INVALID_PARAMETER, "ORG_ID_EMPTY");
@@ -429,6 +429,7 @@ public Mono<ApplicationPermissionView> getApplicationPermissions(String applicat
429429
.creatorId(creatorId)
430430
.orgName(organization.getName())
431431
.publicToAll(application.isPublicToAll())
432+
.publicToMarketplace(application.isPublicToMarketplace())
432433
.build();
433434
});
434435
});
@@ -485,6 +486,7 @@ private ApplicationInfoView buildView(Application application, String role, @Nul
485486
.applicationStatus(application.getApplicationStatus())
486487
.folderId(folderId)
487488
.publicToAll(application.isPublicToAll())
489+
.publicToMarketplace(application.isPublicToMarketplace())
488490
.build();
489491
}
490492

@@ -498,6 +500,12 @@ public Mono<Boolean> setApplicationPublicToAll(String applicationId, boolean pub
498500
.then(applicationService.setApplicationPublicToAll(applicationId, publicToAll));
499501
}
500502

503+
public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, boolean publicToMarketplace) {
504+
return checkCurrentUserApplicationPermission(applicationId, ResourceAction.SET_APPLICATIONS_PUBLIC_TO_MARKETPLACE)
505+
.then(checkApplicationStatus(applicationId, NORMAL))
506+
.then(applicationService.setApplicationPublicToMarketplace(applicationId, publicToMarketplace));
507+
}
508+
501509
private Map<String, Object> sanitizeDsl(Map<String, Object> applicationDsl) {
502510
if (applicationDsl.get("queries") instanceof List<?> queries) {
503511
List<Map<String, Object>> list = queries.stream().map(this::doSanitizeQuery).toList();

‎server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.lowcoder.api.application.view.ApplicationInfoView;
1616
import org.lowcoder.api.application.view.ApplicationPermissionView;
1717
import org.lowcoder.api.application.view.ApplicationView;
18+
import org.lowcoder.api.application.view.MarketplaceApplicationInfoView;
1819
import org.lowcoder.api.framework.view.ResponseView;
1920
import org.lowcoder.api.home.UserHomeApiService;
2021
import org.lowcoder.api.home.UserHomepageView;
@@ -96,6 +97,14 @@ public Mono<ResponseView<ApplicationView>> getPublishedApplication(@PathVariable
9697
.map(ResponseView::success);
9798
}
9899

100+
@Override
101+
public Mono<ResponseView<ApplicationView>> getPublishedMarketPlaceApplication(@PathVariable String applicationId) {
102+
return applicationApiService.getPublishedApplication(applicationId)
103+
.delayUntil(applicationView -> applicationApiService.updateUserApplicationLastViewTime(applicationId))
104+
.delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(applicationView, VIEW))
105+
.map(ResponseView::success);
106+
}
107+
99108
@Override
100109
public Mono<ResponseView<ApplicationView>> update(@PathVariable String applicationId,
101110
@RequestBody Application newApplication) {
@@ -127,6 +136,14 @@ public Mono<ResponseView<List<ApplicationInfoView>>> getApplications(@RequestPar
127136
.map(ResponseView::success);
128137
}
129138

139+
@Override
140+
public Mono<ResponseView<List<MarketplaceApplicationInfoView>>> getMarketplaceApplications(@RequestParam(required = false) Integer applicationType) {
141+
ApplicationType applicationTypeEnum = applicationType == null ? null : ApplicationType.fromValue(applicationType);
142+
return userHomeApiService.getAllMarketplaceApplications(applicationTypeEnum)
143+
.collectList()
144+
.map(ResponseView::success);
145+
}
146+
130147
@Override
131148
public Mono<ResponseView<Boolean>> updatePermission(@PathVariable String applicationId,
132149
@PathVariable String permissionId,
@@ -177,4 +194,11 @@ public Mono<ResponseView<Boolean>> setApplicationPublicToAll(@PathVariable Strin
177194
return applicationApiService.setApplicationPublicToAll(applicationId, request.publicToAll())
178195
.map(ResponseView::success);
179196
}
197+
198+
@Override
199+
public Mono<ResponseView<Boolean>> setApplicationPublicToMarketplace(@PathVariable String applicationId,
200+
@RequestBody ApplicationPublicToMarketplaceRequest request) {
201+
return applicationApiService.setApplicationPublicToMarketplace(applicationId, request.publicToMarketplace())
202+
.map(ResponseView::success);
203+
}
180204
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /