From 081791f8701a9f8f549094e6a8a04f22b7abc20c Mon Sep 17 00:00:00 2001 From: Thomasr Date: Fri, 20 Dec 2024 15:04:24 -0500 Subject: [PATCH 1/2] slug validation --- .../repository/ApplicationRepository.java | 4 +++- .../service/ApplicationServiceImpl.java | 15 ++++++++------- .../service/OrganizationServiceImpl.java | 4 ++++ .../java/org/lowcoder/domain/util/SlugUtils.java | 7 +++++++ .../java/org/lowcoder/sdk/exception/BizError.java | 3 ++- 5 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/util/SlugUtils.java diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java index 4a984b8da..e8ee2ed00 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java @@ -67,6 +67,8 @@ public interface ApplicationRepository extends ReactiveMongoRepository findByPublicToAllIsTrueAndAgencyProfileIsTrue(); - Mono existsBySlug(String slug); + + @Query("{ 'organizationId': ?0, 'slug': ?1 }") + Mono existsByOrganizationIdAndSlug(String organizationId, String slug); } diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationServiceImpl.java index 3b3be763a..9de7ff950 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationServiceImpl.java @@ -18,6 +18,7 @@ import org.lowcoder.domain.permission.model.ResourceType; import org.lowcoder.domain.permission.service.ResourcePermissionService; import org.lowcoder.domain.user.repository.UserRepository; +import org.lowcoder.domain.util.SlugUtils; import org.lowcoder.infra.annotation.NonEmptyMono; import org.lowcoder.infra.mongo.MongoUpsertHelper; import org.lowcoder.sdk.constants.FieldName; @@ -349,15 +350,15 @@ public Mono> getLiveDSLByApplicationId(String applicationId) @Override public Mono updateSlug(String applicationId, String newSlug) { - return repository.existsBySlug(newSlug).flatMap(exists -> { + return repository.findById(applicationId).flatMap(application -> repository.existsByOrganizationIdAndSlug(application.getOrganizationId(), newSlug).flatMap(exists -> { + if (!SlugUtils.validate(newSlug)) { + return Mono.error(new BizException(BizError.INVALID_SLUG, "Slug format is invalid")); + } if (exists) { return Mono.error(new BizException(BizError.DUPLICATE_ENTRY, "Slug already exists")); } - return repository.findById(applicationId) - .flatMap(application -> { - application.setSlug(newSlug); - return repository.save(application); - }); - }); + application.setSlug(newSlug); + return repository.save(application); + })); } } diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java index f1bc1470d..0b1362248 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java @@ -16,6 +16,7 @@ import org.lowcoder.domain.organization.repository.OrganizationRepository; import org.lowcoder.domain.user.model.User; import org.lowcoder.domain.user.repository.UserRepository; +import org.lowcoder.domain.util.SlugUtils; import org.lowcoder.infra.annotation.PossibleEmptyMono; import org.lowcoder.infra.mongo.MongoUpsertHelper; import org.lowcoder.sdk.config.CommonConfig; @@ -292,6 +293,9 @@ private String buildCommonSettingsUpdateTimeKey(String key) { @Override public Mono updateSlug(String organizationId, String newSlug) { return repository.existsBySlug(newSlug).flatMap(exists -> { + if (!SlugUtils.validate(newSlug)) { + return Mono.error(new BizException(BizError.INVALID_SLUG, "Slug format is invalid")); + } if (exists) { return Mono.error(new BizException(BizError.DUPLICATE_ENTRY, "Slug already exists")); } diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/util/SlugUtils.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/util/SlugUtils.java new file mode 100644 index 000000000..be7e138f3 --- /dev/null +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/util/SlugUtils.java @@ -0,0 +1,7 @@ +package org.lowcoder.domain.util; + +public class SlugUtils { + public static Boolean validate(String slug) { + return slug.matches("^[a-zA-Z0-9_-]*$"); + } +} diff --git a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/exception/BizError.java b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/exception/BizError.java index aac1d9565..b43c5e51d 100644 --- a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/exception/BizError.java +++ b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/exception/BizError.java @@ -154,7 +154,8 @@ public enum BizError { ILLEGAL_BUNDLE_PERMISSION_ID(500, 6404), //slug 6501 - 6501 - DUPLICATE_ENTRY(403, 6501); + DUPLICATE_ENTRY(403, 6501), + INVALID_SLUG(403, 6502); static { checkDuplicates(values(), BizError::getBizErrorCode); From 9fd3f286ffa628f078afd1520e40949f8b58359a Mon Sep 17 00:00:00 2001 From: Thomasr Date: Fri, 20 Dec 2024 15:55:22 -0500 Subject: [PATCH 2/2] search by slugs --- .../repository/ApplicationRepository.java | 5 +++++ .../service/ApplicationServiceImpl.java | 14 +++++++----- .../repository/OrganizationRepository.java | 3 +++ .../service/OrganizationServiceImpl.java | 8 +++---- .../org/lowcoder/api/util/GidService.java | 22 ++++++++++++------- .../api/common/TestRedisConfiguration.java | 2 +- 6 files changed, 36 insertions(+), 18 deletions(-) diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java index e8ee2ed00..c320dc0c9 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java @@ -29,6 +29,9 @@ public interface ApplicationRepository extends ReactiveMongoRepository findByGid(@Nonnull String gid); + @Aggregation(pipeline = {"{ $match: { slug: ?0 } }", "{ $project: { 'editingApplicationDSL.settings': 1, _id: 1, gid: 1, organizationId: 1, name: 1, applicationType: 1, applicationStatus: 1, publicToAll: 1, publicToMarketplace: 1, agencyProfile: 1, editingUserId: 1, lastEditedAt: 1, createdAt: 1, updatedAt: 1, createdBy: 1, modifiedBy: 1, _class: 1}}"}) + Flux findBySlug(@Nonnull String slug); + Mono countByOrganizationIdAndApplicationStatus(String organizationId, ApplicationStatus applicationStatus); @Query("{$or : [{'publishedApplicationDSL.queries.datasourceId':?0},{'editingApplicationDSL.queries.datasourceId':?0}]}") @@ -36,9 +39,11 @@ public interface ApplicationRepository extends ReactiveMongoRepository findByIdIn(Collection ids); Flux findByGidIn(Collection ids); + Flux findBySlugIn(Collection slugs); Flux findByCreatedByAndIdIn(String userId, Collection ids); Flux findByCreatedByAndGidIn(String userId, Collection gids); + Flux findByCreatedByAndSlugIn(String userId, Collection slugs); /** * Filter public applications from list of supplied IDs diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationServiceImpl.java index 9de7ff950..e8fc4b791 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationServiceImpl.java @@ -61,9 +61,13 @@ public Mono findByIdWithoutDsl(String id) { return Mono.error(new BizException(BizError.INVALID_PARAMETER, "INVALID_PARAMETER", FieldName.ID)); } - if(FieldName.isGID(id)) - return Mono.from(repository.findByGid(id)).switchIfEmpty(Mono.error(new BizException(BizError.NO_RESOURCE_FOUND, "CANT_FIND_APPLICATION", id))); - return repository.findById(id) + return Mono.from(repository.findBySlug(id)) + .switchIfEmpty( + Mono.defer(() -> { + if (FieldName.isGID(id)) + return Mono.from(repository.findByGid(id)); + return repository.findById(id); + })) .switchIfEmpty(Mono.error(new BizException(BizError.NO_RESOURCE_FOUND, "CANT_FIND_APPLICATION", id))); } @@ -124,7 +128,7 @@ public Mono countByOrganizationId(String orgId, ApplicationStatus applicat public Flux findByIdIn(List applicationIds) { if(!applicationIds.isEmpty() && FieldName.isGID(applicationIds.get(0))) return repository.findByGidIn(applicationIds); - return repository.findByIdIn(applicationIds); + return repository.findBySlugIn(applicationIds).switchIfEmpty(repository.findByIdIn(applicationIds)); } @Override @@ -280,7 +284,7 @@ public Mono> getPrivateApplicationIds(Collection application .map(Application::getGid) .collect(Collectors.toSet()); - return repository.findByCreatedByAndIdIn(userId, applicationIds) + return repository.findByCreatedByAndSlugIn(userId, applicationIds).switchIfEmpty(repository.findByCreatedByAndIdIn(userId, applicationIds)) .map(HasIdAndAuditing::getId) .collect(Collectors.toSet()); } diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/repository/OrganizationRepository.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/repository/OrganizationRepository.java index 13f7d2399..7fceace3e 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/repository/OrganizationRepository.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/repository/OrganizationRepository.java @@ -16,11 +16,14 @@ public interface OrganizationRepository extends ReactiveMongoRepository findByIdInAndState(Collection id, OrganizationState state); Flux findByGidInAndState(Collection gid, OrganizationState state); + Flux findBySlugInAndState(Collection slug, OrganizationState state); Flux findByGid(String gid); + Flux findBySlug(String slug); Flux findByState(OrganizationState state); Mono findByIdAndState(String id, OrganizationState state); Mono findByGidAndState(String gid, OrganizationState state); + Mono findBySlugAndState(String slug, OrganizationState state); Mono findBySourceAndThirdPartyCompanyIdAndState(String source, String tpCompanyId, OrganizationState state); diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java index 0b1362248..5cc9fe87b 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java @@ -170,7 +170,7 @@ public Mono getById(String id) { if(FieldName.isGID(id)) return repository.findByGidAndState(id, ACTIVE) .switchIfEmpty(deferredError(UNABLE_TO_FIND_VALID_ORG, "INVALID_ORG_ID")); - return repository.findByIdAndState(id, ACTIVE) + return repository.findBySlugAndState(id, ACTIVE).switchIfEmpty(repository.findByIdAndState(id, ACTIVE)) .switchIfEmpty(deferredError(UNABLE_TO_FIND_VALID_ORG, "INVALID_ORG_ID")); } @@ -180,7 +180,7 @@ public Mono getOrgCommonSettings(String orgId) { return repository.findByGidAndState(orgId, ACTIVE) .switchIfEmpty(deferredError(UNABLE_TO_FIND_VALID_ORG, "INVALID_ORG_ID")) .map(Organization::getCommonSettings); - return repository.findByIdAndState(orgId, ACTIVE) + return repository.findBySlugAndState(orgId, ACTIVE).switchIfEmpty(repository.findByIdAndState(orgId, ACTIVE)) .switchIfEmpty(deferredError(UNABLE_TO_FIND_VALID_ORG, "INVALID_ORG_ID")) .map(Organization::getCommonSettings); } @@ -189,7 +189,7 @@ public Mono getOrgCommonSettings(String orgId) { public Flux getByIds(Collection ids) { if(!ids.isEmpty() && FieldName.isGID(ids.stream().findFirst().get())) return repository.findByGidInAndState(ids, ACTIVE); - return repository.findByIdInAndState(ids, ACTIVE); + return repository.findBySlugInAndState(ids, ACTIVE).switchIfEmpty(repository.findByIdInAndState(ids, ACTIVE)); } @Override @@ -222,7 +222,7 @@ public Mono uploadLogo(String organizationId, Part filePart) { public Mono deleteLogo(String organizationId) { Mono organizationMono; if(FieldName.isGID(organizationId)) organizationMono = repository.findByGidAndState(organizationId, ACTIVE); - else organizationMono = repository.findByIdAndState(organizationId, ACTIVE); + else organizationMono = repository.findBySlugAndState(organizationId, ACTIVE).switchIfEmpty(repository.findByIdAndState(organizationId, ACTIVE)); return organizationMono .flatMap(organization -> { // delete from asset repo. diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/util/GidService.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/util/GidService.java index 2b9e0ecfc..921bcb164 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/util/GidService.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/util/GidService.java @@ -40,10 +40,13 @@ public class GidService { private BundleRepository bundleRepository; public Mono convertApplicationIdToObjectId(String id) { - if(FieldName.isGID(id)) { - return applicationRepository.findByGid(id).next().mapNotNull(HasIdAndAuditing::getId); - } - return Mono.just(id); + return applicationRepository.findBySlug(id).next().mapNotNull(HasIdAndAuditing::getId).switchIfEmpty( + Mono.defer(() -> { + if (FieldName.isGID(id)) { + return applicationRepository.findByGid(id).next().mapNotNull(HasIdAndAuditing::getId); + } + return Mono.just(id); + })); } public Mono convertDatasourceIdToObjectId(String id) { @@ -54,10 +57,13 @@ public Mono convertDatasourceIdToObjectId(String id) { } public Mono convertOrganizationIdToObjectId(String id) { - if(FieldName.isGID(id)) { - return organizationRepository.findByGid(id).next().mapNotNull(HasIdAndAuditing::getId); - } - return Mono.just(id); + return organizationRepository.findBySlug(id).next().mapNotNull(HasIdAndAuditing::getId).switchIfEmpty( + Mono.defer(() -> { + if(FieldName.isGID(id)) { + return organizationRepository.findByGid(id).next().mapNotNull(HasIdAndAuditing::getId); + } + return Mono.just(id); + })); } public Mono convertGroupIdToObjectId(String id) { diff --git a/server/api-service/lowcoder-server/src/test/java/org/lowcoder/api/common/TestRedisConfiguration.java b/server/api-service/lowcoder-server/src/test/java/org/lowcoder/api/common/TestRedisConfiguration.java index 1119462f2..f42ae0cd4 100644 --- a/server/api-service/lowcoder-server/src/test/java/org/lowcoder/api/common/TestRedisConfiguration.java +++ b/server/api-service/lowcoder-server/src/test/java/org/lowcoder/api/common/TestRedisConfiguration.java @@ -10,7 +10,7 @@ import java.util.concurrent.atomic.AtomicInteger; @SuppressWarnings("UnstableApiUsage") -@TestConfiguration +//@TestConfiguration public class TestRedisConfiguration { private static final AtomicInteger STATE = new AtomicInteger(0); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy