feat: Support for Import/Export without ACL (#18997)

For EE RBAC compatibility, import/export for git sync does not use ACL
This commit is contained in:
sidhantgoel 2022-12-21 23:35:11 +05:30 committed by GitHub
parent 2dc7dc90e3
commit dbb72c4778
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 550 additions and 200 deletions

View File

@ -9,12 +9,15 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface AppsmithRepository<T> {
Mono<T> findById(String id, AclPermission permission);
Mono<T> findById(String id, Optional<AclPermission> permission);
Mono<T> findById(String id, List<String> projectionFieldNames, AclPermission permission);
Mono<T> updateById(String id, T resource, AclPermission permission);
@ -31,5 +34,7 @@ public interface AppsmithRepository<T> {
Mono<T> findByGitSyncIdAndDefaultApplicationId(String defaultApplicationId, String gitSyncId, AclPermission permission);
Mono<T> findByGitSyncIdAndDefaultApplicationId(String defaultApplicationId, String gitSyncId, Optional<AclPermission> permission);
Mono<Boolean> isPermissionPresentForUser(Set<Policy> policies, String permission, String username);
}

View File

@ -14,7 +14,7 @@ import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.client.result.UpdateResult;
import com.querydsl.core.types.Path;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.GenericTypeResolver;
import org.springframework.data.domain.Sort;
@ -60,7 +60,6 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
* ```
* Ref: https://theappsmith.slack.com/archives/CPQNLFHTN/p1669100205502599?thread_ts=1668753437.497369&cid=CPQNLFHTN
*/
@Slf4j
public abstract class BaseAppsmithRepositoryCEImpl<T extends BaseDomain> {
protected final ReactiveMongoOperations mongoOperations;
@ -74,6 +73,7 @@ public abstract class BaseAppsmithRepositoryCEImpl<T extends BaseDomain> {
protected final static int NO_RECORD_LIMIT = -1;
@Autowired
@SuppressWarnings("unchecked")
public BaseAppsmithRepositoryCEImpl(ReactiveMongoOperations mongoOperations,
MongoConverter mongoConverter, CacheableRepositoryHelper cacheableRepositoryHelper) {
this.mongoOperations = mongoOperations;
@ -110,8 +110,8 @@ public abstract class BaseAppsmithRepositoryCEImpl<T extends BaseDomain> {
});
}
public static final String fieldName(Path path) {
return path != null ? path.getMetadata().getName() : null;
public static final String fieldName(Path<?> path) {
return Optional.ofNullable(path).map(p -> p.getMetadata().getName()).orElse("");
}
public static final Criteria notDeleted() {
@ -129,30 +129,36 @@ public abstract class BaseAppsmithRepositoryCEImpl<T extends BaseDomain> {
);
}
@Deprecated
public static final Criteria userAcl(Set<String> permissionGroups, AclPermission permission) {
Optional<Criteria> criteria = userAcl(permissionGroups, Optional.ofNullable(permission));
return criteria.orElse(null);
}
public static final Optional<Criteria> userAcl(Set<String> permissionGroups, Optional<AclPermission> permission) {
if(permission.isEmpty()) {
return Optional.empty();
}
// Check if the permission is being provided by any of the permission groups
Criteria permissionGroupCriteria = Criteria.where(fieldName(QBaseDomain.baseDomain.policies))
.elemMatch(Criteria.where("permissionGroups").in(permissionGroups)
.and("permission").is(permission.getValue()));
.and("permission").is(permission.get().getValue()));
return permissionGroupCriteria;
return Optional.of(permissionGroupCriteria);
}
protected Criteria getIdCriteria(Object id) {
return where("id").is(id);
}
private Criteria getBranchCriteria(String branchName) {
return where(FieldName.DEFAULT_RESOURCES + "." + FieldName.BRANCH_NAME).is(branchName);
}
protected DBObject getDbObject(Object o) {
BasicDBObject basicDBObject = new BasicDBObject();
mongoConverter.write(o, basicDBObject);
return basicDBObject;
}
@Deprecated
public Mono<T> findById(String id, AclPermission permission) {
return findById(id, null, permission);
}
@ -161,60 +167,69 @@ public abstract class BaseAppsmithRepositoryCEImpl<T extends BaseDomain> {
if (id == null) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID));
}
return ReactiveSecurityContextHolder.getContext()
.map(ctx -> ctx.getAuthentication())
.map(auth -> auth.getPrincipal())
.flatMap(principal -> getAllPermissionGroupsForUser((User) principal))
.flatMap(permissionGroups -> {
Query query = new Query(getIdCriteria(id));
query.addCriteria(new Criteria().andOperator(notDeleted(), userAcl(permissionGroups, permission)));
if(!isEmpty(projectionFieldNames)) {
projectionFieldNames.stream()
.forEach(projectionFieldName -> {
query.fields().include(projectionFieldName);
});
}
return mongoOperations.query(this.genericDomain)
.matching(query)
.one()
.flatMap(obj -> setUserPermissionsInObject(obj, permissionGroups));
});
return findById(id, Optional.ofNullable(permission));
}
public Mono<T> findById(String id, Optional<AclPermission> permission) {
return getCurrentUserPermissionGroupsIfRequired(permission).flatMap(permissionGroups -> {
Query query = new Query(getIdCriteria(id));
query.addCriteria(notDeleted());
Optional<Criteria> userAcl = userAcl(permissionGroups, permission);
if(userAcl.isPresent()) {
query.addCriteria(userAcl.get());
}
return mongoOperations.query(this.genericDomain)
.matching(query)
.one()
.flatMap(obj -> setUserPermissionsInObject(obj, permissionGroups));
});
}
@Deprecated
public Mono<T> updateById(String id, T resource, AclPermission permission) {
if (id == null) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID));
}
if (resource == null) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID));
}
return updateById(id, resource, Optional.ofNullable(permission));
}
public Mono<T> updateById(String id, T resource, Optional<AclPermission> permission) {
Query query = new Query(Criteria.where("id").is(id));
// Set policies to null in the update object
resource.setPolicies(null);
resource.setUpdatedAt(Instant.now());
DBObject update = getDbObject(resource);
Update updateObj = new Update();
update.keySet().stream().forEach(entry -> updateObj.set(entry, update.get(entry)));
return ReactiveSecurityContextHolder.getContext()
.map(ctx -> ctx.getAuthentication())
.map(auth -> auth.getPrincipal())
.zipWhen(principal -> getAllPermissionGroupsForUser((User) principal))
.flatMap(touple -> {
User user = (User) touple.getT1();
Set<String> permissionGroups = touple.getT2();
Query query = new Query(Criteria.where("id").is(id));
query.addCriteria(new Criteria().andOperator(notDeleted(), userAcl(permissionGroups, permission)));
// Set policies to null in the update object
resource.setPolicies(null);
resource.setUpdatedAt(Instant.now());
.map(auth -> (User) auth.getPrincipal())
.flatMap(user -> {
resource.setModifiedBy(user.getUsername());
DBObject update = getDbObject(resource);
Update updateObj = new Update();
Map<String, Object> updateMap = update.toMap();
updateMap.entrySet().stream().forEach(entry -> updateObj.set(entry.getKey(), entry.getValue()));
return mongoOperations.updateFirst(query, updateObj, resource.getClass())
.flatMap(obj -> {
if (obj.getMatchedCount() == 0) {
return Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, resource.getClass().getSimpleName().toLowerCase(), id));
return (permission.isPresent() ? getAllPermissionGroupsForUser(user) : Mono.just(Set.<String>of()))
.flatMap(permissionGroups -> {
Optional<Criteria> userAcl = userAcl(permissionGroups, permission);
query.addCriteria(notDeleted());
if(userAcl.isPresent()) {
query.addCriteria(userAcl.get());
}
return findById(id, permission);
})
.flatMap(obj -> setUserPermissionsInObject(obj, permissionGroups));
return mongoOperations.updateFirst(query, updateObj, resource.getClass())
.flatMap(obj -> {
if (obj.getMatchedCount() == 0) {
return Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, resource.getClass().getSimpleName().toLowerCase(), id));
}
return findById(id, permission);
})
.flatMap(obj -> {
return setUserPermissionsInObject(obj, permissionGroups);
});
});
});
}
@ -246,13 +261,21 @@ public abstract class BaseAppsmithRepositoryCEImpl<T extends BaseDomain> {
if (id == null) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID));
}
return ReactiveSecurityContextHolder.getContext()
.map(ctx -> ctx.getAuthentication())
.map(auth -> auth.getPrincipal())
.flatMap(principal -> getAllPermissionGroupsForUser((User) principal))
.flatMap(permissionGroups -> {
Query query = new Query(Criteria.where("id").is(id));
query.addCriteria(new Criteria().andOperator(notDeleted(), userAcl(permissionGroups, permission)));
if (updateObj == null) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID));
}
return updateById(id, updateObj, Optional.ofNullable(permission));
}
public Mono<UpdateResult> updateById(String id, Update updateObj, Optional<AclPermission> permission) {
Query query = new Query(Criteria.where("id").is(id));
if(permission.isEmpty()) {
return mongoOperations.updateFirst(query, updateObj, this.genericDomain);
}
return getCurrentUserPermissionGroupsIfRequired(permission).flatMap(permissionGroups -> {
query.addCriteria(new Criteria().andOperator(notDeleted(), userAcl(permissionGroups, permission.get())));
return mongoOperations.updateFirst(query, updateObj, this.genericDomain);
});
}
@ -261,47 +284,81 @@ public abstract class BaseAppsmithRepositoryCEImpl<T extends BaseDomain> {
if (criteriaList == null) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, "criteriaList"));
}
if (updateObj == null) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, "updateObj"));
}
List<Criteria> allCriterias = new ArrayList<>(criteriaList);
allCriterias.add(notDeleted());
Query query = new Query(new Criteria().andOperator(allCriterias));
return mongoOperations.updateMulti(query, updateObj, this.genericDomain);
}
@Deprecated
protected Mono<T> queryOne(List<Criteria> criterias, AclPermission aclPermission) {
return queryOne(criterias, null, aclPermission);
return queryOne(criterias, Optional.ofNullable(aclPermission));
}
protected Mono<T> queryOne(List<Criteria> criterias, List<String> projectionFieldNames, AclPermission aclPermission) {
protected Mono<Set<String>> getCurrentUserPermissionGroupsIfRequired(Optional<AclPermission> permission) {
if(permission.isEmpty()) {
return Mono.just(Set.of());
}
return getCurrentUserPermissionGroups();
}
protected Mono<Set<String>> getCurrentUserPermissionGroups() {
return ReactiveSecurityContextHolder.getContext()
.map(ctx -> ctx.getAuthentication())
.map(auth -> auth.getPrincipal())
.flatMap(principal -> getAllPermissionGroupsForUser((User) principal))
.flatMap(permissionGroups -> {
.flatMap(principal -> getAllPermissionGroupsForUser((User) principal));
}
protected Mono<T> queryOne(List<Criteria> criterias, List<String> projectionFieldNames, AclPermission permission) {
Mono<Set<String>> permissionGroupsMono = getCurrentUserPermissionGroupsIfRequired(Optional.ofNullable(permission));
return permissionGroupsMono.flatMap(permissionGroups -> {
return mongoOperations.query(this.genericDomain)
.matching(createQueryWithPermission(criterias, projectionFieldNames, permissionGroups, aclPermission))
.matching(createQueryWithPermission(criterias, projectionFieldNames, permissionGroups, permission))
.one()
.flatMap(obj -> setUserPermissionsInObject(obj, permissionGroups));
});
}
protected Mono<T> queryFirst(List<Criteria> criterias, AclPermission aclPermission) {
return ReactiveSecurityContextHolder.getContext()
.map(ctx -> ctx.getAuthentication())
.map(auth -> auth.getPrincipal())
.flatMap(principal -> getAllPermissionGroupsForUser((User) principal))
.flatMap(permissionGroups -> {
protected Mono<T> queryOne(List<Criteria> criterias, Optional<AclPermission> permission) {
Mono<Set<String>> permissionGroupsMono = getCurrentUserPermissionGroupsIfRequired(permission);
return permissionGroupsMono.flatMap(permissionGroups -> {
return mongoOperations.query(this.genericDomain)
.matching(createQueryWithPermission(criterias, permissionGroups, aclPermission))
.first()
.matching(createQueryWithPermission(criterias, permissionGroups, permission))
.one()
.flatMap(obj -> setUserPermissionsInObject(obj, permissionGroups));
});
}
protected Query createQueryWithPermission(List<Criteria> criterias, Set<String> permissionGroups,
AclPermission aclPermission) {
@Deprecated
protected Mono<T> queryFirst(List<Criteria> criterias, AclPermission aclPermission) {
return queryFirst(criterias, Optional.ofNullable(aclPermission));
}
protected Mono<T> queryFirst(List<Criteria> criterias, Optional<AclPermission> permission) {
Mono<Set<String>> permissionGroupsMono = getCurrentUserPermissionGroupsIfRequired(permission);
return permissionGroupsMono.flatMap(permissionGroups -> {
return mongoOperations.query(this.genericDomain)
.matching(createQueryWithPermission(criterias, permissionGroups, permission))
.first()
.flatMap(obj -> setUserPermissionsInObject(obj, permissionGroups));
});
}
@Deprecated
protected Query createQueryWithPermission(List<Criteria> criterias, Set<String> permissionGroups, AclPermission aclPermission) {
return createQueryWithPermission(criterias, null, permissionGroups, aclPermission);
}
protected Query createQueryWithPermission(List<Criteria> criterias, Set<String> permissionGroups, Optional<AclPermission> permission) {
return createQueryWithPermission(criterias, null, permissionGroups, permission.orElse(null));
}
protected Query createQueryWithPermission(List<Criteria> criterias, List<String> projectionFieldNames,
Set<String> permissionGroups,
AclPermission aclPermission) {
@ -322,76 +379,91 @@ public abstract class BaseAppsmithRepositoryCEImpl<T extends BaseDomain> {
return query;
}
@Deprecated
protected Mono<Long> count(List<Criteria> criterias, AclPermission aclPermission) {
return ReactiveSecurityContextHolder.getContext()
.map(ctx -> ctx.getAuthentication())
.map(auth -> auth.getPrincipal())
.flatMap(principal -> getAllPermissionGroupsForUser((User) principal))
.flatMap(permissionGroups ->
mongoOperations.count(
createQueryWithPermission(criterias, permissionGroups, aclPermission), this.genericDomain
)
);
return count(criterias, Optional.ofNullable(aclPermission));
}
protected Mono<Long> count(List<Criteria> criteriaList) {
return mongoOperations.count(
createQueryWithPermission(criteriaList, null, null), this.genericDomain
protected Mono<Long> count(List<Criteria> criterias, Optional<AclPermission> permission) {
Mono<Set<String>> permissionGroupsMono = getCurrentUserPermissionGroupsIfRequired(permission);
return permissionGroupsMono.flatMap(permissionGroups ->
mongoOperations.count(createQueryWithPermission(criterias, permissionGroups, permission), this.genericDomain)
);
}
protected Mono<Long> count(List<Criteria> criteriaList) {
return count(criteriaList, Optional.empty());
}
@Deprecated
public Flux<T> queryAll(List<Criteria> criterias, AclPermission aclPermission) {
return queryAll(criterias, aclPermission, null);
return queryAll(criterias, Optional.empty(), Optional.ofNullable(aclPermission), Optional.empty(), NO_RECORD_LIMIT);
}
public Flux<T> queryAll(List<Criteria> criterias, Optional<AclPermission> permission) {
return queryAll(criterias, permission, Optional.empty());
}
@Deprecated
public Flux<T> queryAll(List<Criteria> criterias, AclPermission aclPermission, Sort sort) {
return queryAll(criterias, null, aclPermission, sort);
return queryAll(criterias, Optional.empty(), Optional.ofNullable(aclPermission), Optional.ofNullable(sort), NO_RECORD_LIMIT);
}
public Flux<T> queryAll(List<Criteria> criterias, Optional<AclPermission> permission, Optional<Sort> sort) {
return queryAll(criterias, Optional.empty(), permission, sort, NO_RECORD_LIMIT);
}
@Deprecated
public Flux<T> queryAll(List<Criteria> criterias, List<String> includeFields, AclPermission aclPermission, Sort sort) {
return queryAll(criterias, Optional.ofNullable(includeFields), Optional.ofNullable(aclPermission), Optional.ofNullable(sort), NO_RECORD_LIMIT);
}
public Flux<T> queryAll(List<Criteria> criterias, Optional<List<String>> includeFields, Optional<AclPermission> aclPermission, Optional<Sort> sort) {
return queryAll(criterias, includeFields, aclPermission, sort, NO_RECORD_LIMIT);
}
@Deprecated
public Flux<T> queryAll(List<Criteria> criterias, List<String> includeFields, AclPermission aclPermission, Sort sort, int limit) {
final ArrayList<Criteria> criteriaList = new ArrayList<>(criterias);
return ReactiveSecurityContextHolder.getContext()
.map(ctx -> ctx.getAuthentication())
.map(auth -> auth.getPrincipal())
.flatMap(principal -> getAllPermissionGroupsForUser((User) principal))
.flatMapMany(permissionGroups -> queryAllWithPermissionGroups(criteriaList, includeFields, aclPermission, sort, permissionGroups, limit));
return queryAll(criterias, Optional.ofNullable(includeFields), Optional.ofNullable(aclPermission), Optional.ofNullable(sort), limit);
}
public Flux<T> queryAll( List<Criteria> criterias, Optional<List<String>> includeFields, Optional<AclPermission> permission, Optional<Sort> sort, int limit) {
final ArrayList<Criteria> criteriaList = new ArrayList<>(criterias);
Mono<Set<String>> permissionGroupsMono = getCurrentUserPermissionGroupsIfRequired(permission);
return permissionGroupsMono.flatMapMany(permissionGroups -> queryAllWithPermissionGroups(criterias, includeFields, permission, sort, permissionGroups, limit));
}
@Deprecated
public Flux<T> queryAllWithPermissionGroups(List<Criteria> criterias,
List<String> includeFields,
AclPermission aclPermission,
Sort sort,
Set<String> permissionGroups,
int limit) {
return queryAllWithPermissionGroups(criterias, Optional.ofNullable(includeFields), Optional.ofNullable(aclPermission), Optional.ofNullable(sort), permissionGroups, limit);
}
public Flux<T> queryAllWithPermissionGroups(List<Criteria> criterias,
Optional<List<String>> includeFields,
Optional<AclPermission> aclPermission,
Optional<Sort> sortOptional,
Set<String> permissionGroups,
int limit) {
final ArrayList<Criteria> criteriaList = new ArrayList<>(criterias);
Query query = new Query();
if (!CollectionUtils.isEmpty(includeFields)) {
for (String includeField : includeFields) {
query.fields().include(includeField);
}
}
includeFields.ifPresent(fields -> {
fields.forEach(field -> query.fields().include(field));
});
if (limit != NO_RECORD_LIMIT) {
query.limit(limit);
}
Criteria andCriteria = new Criteria();
criteriaList.add(notDeleted());
if (aclPermission != null) {
criteriaList.add(userAcl(permissionGroups, aclPermission));
}
userAcl(permissionGroups, aclPermission).ifPresent(criteria -> criteriaList.add(criteria));
andCriteria.andOperator(criteriaList.toArray(new Criteria[0]));
query.addCriteria(andCriteria);
if (sort != null) {
query.with(sort);
}
sortOptional.ifPresent(sort-> query.with(sort));
return mongoOperations.query(this.genericDomain)
.matching(query)
.all()
@ -399,17 +471,15 @@ public abstract class BaseAppsmithRepositoryCEImpl<T extends BaseDomain> {
}
public Mono<T> setUserPermissionsInObject(T obj) {
return ReactiveSecurityContextHolder.getContext()
.map(ctx -> ctx.getAuthentication())
.map(auth -> auth.getPrincipal())
.flatMap(principal -> getAllPermissionGroupsForUser((User) principal))
return getCurrentUserPermissionGroups()
.flatMap(permissionGroups -> setUserPermissionsInObject(obj, permissionGroups));
}
public Mono<T> setUserPermissionsInObject(T obj, Set<String> permissionGroups) {
Set<String> permissions = new HashSet<>();
obj.setUserPermissions(permissions);
if (CollectionUtils.isEmpty(obj.getPolicies())) {
if (CollectionUtils.isEmpty(obj.getPolicies()) || permissionGroups.isEmpty()) {
return Mono.just(obj);
}
@ -426,11 +496,15 @@ public abstract class BaseAppsmithRepositoryCEImpl<T extends BaseDomain> {
}
}
obj.setUserPermissions(permissions);
return Mono.just(obj);
}
@Deprecated
public Mono<T> findByGitSyncIdAndDefaultApplicationId(String defaultApplicationId, String gitSyncId, AclPermission permission) {
return findByGitSyncIdAndDefaultApplicationId(defaultApplicationId, gitSyncId, Optional.ofNullable(permission));
}
public Mono<T> findByGitSyncIdAndDefaultApplicationId(String defaultApplicationId, String gitSyncId, Optional<AclPermission> permission) {
final String defaultResources = fieldName(QBaseDomain.baseDomain.defaultResources);
Criteria defaultAppIdCriteria = where(defaultResources + "." + FieldName.APPLICATION_ID).is(defaultApplicationId);
Criteria gitSyncIdCriteria = where(FieldName.GIT_SYNC_ID).is(gitSyncId);

View File

@ -8,11 +8,14 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Optional;
public interface CustomActionCollectionRepositoryCE extends AppsmithRepository<ActionCollection> {
Flux<ActionCollection> findByApplicationId(String applicationId, AclPermission aclPermission, Sort sort);
Flux<ActionCollection> findByApplicationId(String applicationId, Optional<AclPermission> aclPermission, Optional<Sort> sort);
Flux<ActionCollection> findByApplicationIdAndViewMode(String applicationId, boolean viewMode, AclPermission aclPermission);
Flux<ActionCollection> findAllActionCollectionsByNamePageIdsViewModeAndBranch(String name, List<String> pageIds, boolean viewMode, String branchName, AclPermission aclPermission, Sort sort);

View File

@ -16,6 +16,7 @@ import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static org.springframework.data.mongodb.core.query.Criteria.where;
@ -28,6 +29,7 @@ public class CustomActionCollectionRepositoryCEImpl extends BaseAppsmithReposito
@Override
@Deprecated
public Flux<ActionCollection> findByApplicationId(String applicationId, AclPermission aclPermission, Sort sort) {
Criteria applicationCriteria = where(fieldName(QActionCollection.actionCollection.applicationId)).is(applicationId);
@ -35,6 +37,14 @@ public class CustomActionCollectionRepositoryCEImpl extends BaseAppsmithReposito
return queryAll(List.of(applicationCriteria), aclPermission, sort);
}
@Override
public Flux<ActionCollection> findByApplicationId(String applicationId, Optional<AclPermission> aclPermission, Optional<Sort> sort) {
Criteria applicationCriteria = where(fieldName(QActionCollection.actionCollection.applicationId)).is(applicationId);
return queryAll(List.of(applicationCriteria), aclPermission, sort);
}
@Override
public Flux<ActionCollection> findByApplicationIdAndViewMode(String applicationId, boolean viewMode, AclPermission aclPermission) {

View File

@ -10,6 +10,7 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.Map;
@ -42,6 +43,8 @@ public interface CustomApplicationRepositoryCE extends AppsmithRepository<Applic
Mono<UpdateResult> setGitAuth(String applicationId, GitAuth gitAuth, AclPermission aclPermission);
Mono<Application> getApplicationByGitBranchAndDefaultApplicationId(String defaultApplicationId, String branchName, Optional<AclPermission> permission);
Mono<Application> getApplicationByGitBranchAndDefaultApplicationId(String defaultApplicationId, String branchName, AclPermission aclPermission);
Mono<Application> getApplicationByGitBranchAndDefaultApplicationId(String defaultApplicationId,

View File

@ -27,6 +27,7 @@ import reactor.core.publisher.Mono;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.Map;
import java.util.Set;
@ -163,6 +164,7 @@ public class CustomApplicationRepositoryCEImpl extends BaseAppsmithRepositoryImp
}
@Override
@Deprecated
public Mono<Application> getApplicationByGitBranchAndDefaultApplicationId(String defaultApplicationId, String branchName, AclPermission aclPermission) {
return getApplicationByGitBranchAndDefaultApplicationId(defaultApplicationId, null, branchName, aclPermission);
}
@ -179,6 +181,16 @@ public class CustomApplicationRepositoryCEImpl extends BaseAppsmithRepositoryImp
return queryOne(List.of(defaultAppCriteria, branchNameCriteria), projectionFieldNames, aclPermission);
}
@Override
public Mono<Application> getApplicationByGitBranchAndDefaultApplicationId(String defaultApplicationId, String branchName, Optional<AclPermission> aclPermission) {
String gitApplicationMetadata = fieldName(QApplication.application.gitApplicationMetadata);
Criteria defaultAppCriteria = where(gitApplicationMetadata + "." + fieldName(QApplication.application.gitApplicationMetadata.defaultApplicationId)).is(defaultApplicationId);
Criteria branchNameCriteria = where(gitApplicationMetadata + "." + fieldName(QApplication.application.gitApplicationMetadata.branchName)).is(branchName);
return queryOne(List.of(defaultAppCriteria, branchNameCriteria), aclPermission);
}
@Override
public Flux<Application> getApplicationByGitDefaultApplicationId(String defaultApplicationId, AclPermission permission) {
String gitApplicationMetadata = fieldName(QApplication.application.gitApplicationMetadata);

View File

@ -8,14 +8,19 @@ import com.mongodb.client.result.UpdateResult;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Optional;
import java.util.Set;
public interface CustomDatasourceRepositoryCE extends AppsmithRepository<Datasource> {
Flux<Datasource> findAllByWorkspaceId(String workspaceId, AclPermission permission);
Flux<Datasource> findAllByWorkspaceId(String workspaceId, Optional<AclPermission> permission);
Mono<Datasource> findByNameAndWorkspaceId(String name, String workspaceId, AclPermission aclPermission);
Mono<Datasource> findByNameAndWorkspaceId(String name, String workspaceId, Optional<AclPermission> permission);
Mono<Datasource> findById(String id, AclPermission aclPermission);
Flux<Datasource> findAllByIds(Set<String> ids, AclPermission permission);

View File

@ -16,6 +16,7 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import static org.springframework.data.mongodb.core.query.Criteria.where;
@ -28,18 +29,33 @@ public class CustomDatasourceRepositoryCEImpl extends BaseAppsmithRepositoryImpl
}
@Override
@Deprecated
public Flux<Datasource> findAllByWorkspaceId(String workspaceId, AclPermission permission) {
Criteria workspaceIdCriteria = where(fieldName(QDatasource.datasource.workspaceId)).is(workspaceId);
return queryAll(List.of(workspaceIdCriteria), permission, Sort.by(fieldName(QDatasource.datasource.name)));
}
@Override
public Flux<Datasource> findAllByWorkspaceId(String workspaceId, Optional<AclPermission> permission) {
Criteria workspaceIdCriteria = where(fieldName(QDatasource.datasource.workspaceId)).is(workspaceId);
return queryAll(List.of(workspaceIdCriteria), permission, Optional.of(Sort.by(fieldName(QDatasource.datasource.name))));
}
@Override
@Deprecated
public Mono<Datasource> findByNameAndWorkspaceId(String name, String workspaceId, AclPermission aclPermission) {
Criteria nameCriteria = where(fieldName(QDatasource.datasource.name)).is(name);
Criteria workspaceIdCriteria = where(fieldName(QDatasource.datasource.workspaceId)).is(workspaceId);
return queryOne(List.of(nameCriteria, workspaceIdCriteria), aclPermission);
}
@Override
public Mono<Datasource> findByNameAndWorkspaceId(String name, String workspaceId, Optional<AclPermission> aclPermission) {
Criteria nameCriteria = where(fieldName(QDatasource.datasource.name)).is(name);
Criteria workspaceIdCriteria = where(fieldName(QDatasource.datasource.workspaceId)).is(workspaceId);
return queryOne(List.of(nameCriteria, workspaceIdCriteria), aclPermission);
}
@Override
public Flux<Datasource> findAllByIds(Set<String> ids, AclPermission permission) {
Criteria idcriteria = where(fieldName(QDatasource.datasource.id)).in(ids);

View File

@ -11,6 +11,7 @@ import org.springframework.data.mongodb.core.query.Criteria;
import reactor.core.publisher.Flux;
import java.util.List;
import java.util.Optional;
import static org.springframework.data.mongodb.core.query.Criteria.where;
@ -26,6 +27,6 @@ public class CustomGroupRepositoryCEImpl extends BaseAppsmithRepositoryImpl<Grou
public Flux<Group> getAllByWorkspaceId(String workspaceId) {
Criteria workspaceIdCriteria = where(fieldName(QGroup.group.workspaceId)).is(workspaceId);
return queryAll(List.of(workspaceIdCriteria), null);
return queryAll(List.of(workspaceIdCriteria), Optional.empty());
}
}

View File

@ -8,6 +8,7 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface CustomNewActionRepositoryCE extends AppsmithRepository<NewAction> {
@ -18,6 +19,8 @@ public interface CustomNewActionRepositoryCE extends AppsmithRepository<NewActio
Flux<NewAction> findByPageId(String pageId, AclPermission aclPermission);
Flux<NewAction> findByPageId(String pageId, Optional<AclPermission> aclPermission);
Flux<NewAction> findByPageId(String pageId);
Flux<NewAction> findByPageIdAndViewMode(String pageId, Boolean viewMode, AclPermission aclPermission);
@ -38,6 +41,8 @@ public interface CustomNewActionRepositoryCE extends AppsmithRepository<NewActio
Flux<NewAction> findByApplicationId(String applicationId, AclPermission aclPermission, Sort sort);
Flux<NewAction> findByApplicationId(String applicationId, Optional<AclPermission> aclPermission, Optional<Sort> sort);
Flux<NewAction> findByApplicationIdAndViewMode(String applicationId, Boolean viewMode, AclPermission aclPermission);
Mono<Long> countByDatasourceId(String datasourceId);

View File

@ -19,6 +19,7 @@ import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import static org.springframework.data.mongodb.core.query.Criteria.where;
@ -38,6 +39,12 @@ public class CustomNewActionRepositoryCEImpl extends BaseAppsmithRepositoryImpl<
return queryAll(List.of(applicationIdCriteria), aclPermission);
}
@Override
public Flux<NewAction> findByApplicationId(String applicationId, Optional<AclPermission> aclPermission, Optional<Sort> sort) {
Criteria applicationIdCriteria = where(fieldName(QNewAction.newAction.applicationId)).is(applicationId);
return queryAll(List.of(applicationIdCriteria), aclPermission, sort);
}
@Override
public Mono<NewAction> findByUnpublishedNameAndPageId(String name, String pageId, AclPermission aclPermission) {
Criteria nameCriteria = where(fieldName(QNewAction.newAction.unpublishedAction) + "." + fieldName(QNewAction.newAction.unpublishedAction.name)).is(name);
@ -61,9 +68,22 @@ public class CustomNewActionRepositoryCEImpl extends BaseAppsmithRepositoryImpl<
return queryAll(List.of(pageCriteria), aclPermission);
}
@Override
public Flux<NewAction> findByPageId(String pageId, Optional<AclPermission> aclPermission) {
String unpublishedPage = fieldName(QNewAction.newAction.unpublishedAction) + "." + fieldName(QNewAction.newAction.unpublishedAction.pageId);
String publishedPage = fieldName(QNewAction.newAction.publishedAction) + "." + fieldName(QNewAction.newAction.publishedAction.pageId);
Criteria pageCriteria = new Criteria().orOperator(
where(unpublishedPage).is(pageId),
where(publishedPage).is(pageId)
);
return queryAll(List.of(pageCriteria), aclPermission);
}
@Override
public Flux<NewAction> findByPageId(String pageId) {
return this.findByPageId(pageId, null);
return this.findByPageId(pageId, Optional.empty());
}
@Override

View File

@ -7,11 +7,15 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Optional;
public interface CustomNewPageRepositoryCE extends AppsmithRepository<NewPage> {
@Deprecated
Flux<NewPage> findByApplicationId(String applicationId, AclPermission aclPermission);
Flux<NewPage> findByApplicationId(String applicationId, Optional<AclPermission> permission);
Flux<NewPage> findByApplicationIdAndNonDeletedEditMode(String applicationId, AclPermission aclPermission);
Mono<NewPage> findByIdAndLayoutsIdAndViewMode(String id, String layoutId, AclPermission aclPermission, Boolean viewMode);

View File

@ -18,6 +18,7 @@ import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static org.springframework.data.mongodb.core.query.Criteria.where;
@ -35,6 +36,12 @@ public class CustomNewPageRepositoryCEImpl extends BaseAppsmithRepositoryImpl<Ne
return queryAll(List.of(applicationIdCriteria), aclPermission);
}
@Override
public Flux<NewPage> findByApplicationId(String applicationId, Optional<AclPermission> permission) {
Criteria applicationIdCriteria = where(fieldName(QNewPage.newPage.applicationId)).is(applicationId);
return queryAll(List.of(applicationIdCriteria), permission);
}
@Override
public Flux<NewPage> findByApplicationIdAndNonDeletedEditMode(String applicationId, AclPermission aclPermission) {
Criteria applicationIdCriteria = where(fieldName(QNewPage.newPage.applicationId)).is(applicationId);

View File

@ -46,12 +46,14 @@ public class GitServiceImpl extends GitServiceCEImpl implements GitService {
DatasourcePermission datasourcePermission,
ApplicationPermission applicationPermission,
PagePermission pagePermission,
ActionPermission actionPermission) {
ActionPermission actionPermission,
WorkspaceService workspaceService) {
super(userService, userDataService, sessionUserService, applicationService, applicationPageService,
newPageService, newActionService, actionCollectionService, fileUtils, importExportApplicationService,
gitExecutor, responseUtils, emailConfig, analyticsService, gitCloudServicesUtils, gitDeployKeysRepository,
datasourceService, pluginService, datasourcePermission, applicationPermission, pagePermission,
actionPermission);
actionPermission, workspaceService);
}
}

View File

@ -37,6 +37,8 @@ public interface ActionCollectionServiceCE extends CrudService<ActionCollection,
Mono<ActionCollectionDTO> update(String id, ActionCollectionDTO actionCollectionDTO);
Mono<ActionCollectionDTO> deleteUnpublishedActionCollection(String id);
Mono<ActionCollectionDTO> deleteWithoutPermissionUnpublishedActionCollection(String id);
Mono<ActionCollectionDTO> deleteUnpublishedActionCollection(String id, String branchName);

View File

@ -45,6 +45,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -322,9 +323,18 @@ public class ActionCollectionServiceCEImpl extends BaseService<ActionCollectionR
false)));
}
@Override
public Mono<ActionCollectionDTO> deleteWithoutPermissionUnpublishedActionCollection(String id) {
return deleteUnpublishedActionCollectionEx(id, Optional.empty());
}
@Override
public Mono<ActionCollectionDTO> deleteUnpublishedActionCollection(String id) {
Mono<ActionCollection> actionCollectionMono = repository.findById(id, actionPermission.getDeletePermission())
return deleteUnpublishedActionCollectionEx(id, Optional.of(actionPermission.getDeletePermission()));
}
public Mono<ActionCollectionDTO> deleteUnpublishedActionCollectionEx(String id, Optional<AclPermission> permission) {
Mono<ActionCollection> actionCollectionMono = repository.findById(id, permission)
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ACTION_COLLECTION, id)));
return actionCollectionMono
.flatMap(toDelete -> {

View File

@ -45,6 +45,8 @@ public interface ApplicationPageServiceCE {
Mono<PageDTO> deleteUnpublishedPage(String id);
Mono<PageDTO> deleteWithoutPermissionUnpublishedPage(String id);
Mono<Application> publish(String applicationId, boolean isPublishedManually);
Mono<Application> publish(String defaultApplicationId, String branchName, boolean isPublishedManually);

View File

@ -831,9 +831,31 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE {
* @return
*/
@Override
public Mono<PageDTO> deleteUnpublishedPage(String id) {
public Mono<PageDTO> deleteWithoutPermissionUnpublishedPage(String id) {
return deleteUnpublishedPageEx(id, Optional.empty());
}
return newPageService.findById(id, pagePermission.getDeletePermission())
@Override
public Mono<PageDTO> deleteUnpublishedPage(String id) {
return deleteUnpublishedPageEx(id, Optional.of(pagePermission.getDeletePermission()));
}
/**
* This function archives the unpublished page. This also archives the unpublished action. The reason that the
* entire action is not deleted at this point is to handle the following edge case :
* An application is published with 1 page and 1 action.
* Post publish, create a new page and move the action from the existing page to the new page. Now delete this newly
* created page.
* In this scenario, if we were to delete all actions associated with the page, we would end up deleting an action
* which is currently in published state and is being used.
*
* @param id The pageId which needs to be archived.
* @return
*/
private Mono<PageDTO> deleteUnpublishedPageEx(String id, Optional<AclPermission> permission) {
return newPageService.findById(id, permission)
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, id)))
.flatMap(page -> {
log.debug("Going to archive pageId: {} for applicationId: {}", page.getId(), page.getApplicationId());

View File

@ -1,5 +1,8 @@
package com.appsmith.server.services.ce;
import java.util.Optional;
import com.appsmith.server.acl.AclPermission;
import com.appsmith.server.domains.Application;
import com.appsmith.server.domains.GitAuth;
@ -21,6 +24,8 @@ public interface ApplicationServiceCE extends CrudService<Application, String> {
Mono<Application> findById(String id, AclPermission aclPermission);
Mono<Application> findById(String id, Optional<AclPermission> aclPermission);
Mono<Application> findByIdAndWorkspaceId(String id, String workspaceId, AclPermission permission);
Flux<Application> findByWorkspaceId(String workspaceId, AclPermission permission);
@ -61,6 +66,8 @@ public interface ApplicationServiceCE extends CrudService<Application, String> {
String defaultApplicationId,
AclPermission aclPermission);
Mono<String> findBranchedApplicationId(Optional<String> branchName, String defaultApplicationId, Optional<AclPermission> permission);
Mono<Application> findByBranchNameAndDefaultApplicationId(String branchName,
String defaultApplicationId,
List<String> projectionFieldNames,

View File

@ -58,6 +58,7 @@ import java.time.Instant;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import static com.appsmith.server.acl.AclPermission.MANAGE_APPLICATIONS;
@ -170,11 +171,18 @@ public class ApplicationServiceCEImpl extends BaseService<ApplicationRepository,
}
@Override
@Deprecated
public Mono<Application> findById(String id, AclPermission aclPermission) {
return repository.findById(id, aclPermission)
.flatMap(this::setTransientFields);
}
@Override
public Mono<Application> findById(String id, Optional<AclPermission> aclPermission) {
return repository.findById(id, aclPermission)
.flatMap(this::setTransientFields);
}
@Override
public Mono<Application> findByIdAndWorkspaceId(String id, String workspaceId, AclPermission permission) {
return repository.findByIdAndWorkspaceId(id, workspaceId, permission)
@ -679,8 +687,8 @@ public class ApplicationServiceCEImpl extends BaseService<ApplicationRepository,
}
public Mono<String> findBranchedApplicationId(String branchName, String defaultApplicationId, AclPermission permission) {
if (StringUtils.isEmpty(branchName)) {
if (StringUtils.isEmpty(defaultApplicationId)) {
if (!StringUtils.hasLength(branchName)) {
if (!StringUtils.hasLength(defaultApplicationId)) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.APPLICATION_ID, defaultApplicationId));
}
return Mono.just(defaultApplicationId);
@ -692,6 +700,20 @@ public class ApplicationServiceCEImpl extends BaseService<ApplicationRepository,
.map(Application::getId);
}
public Mono<String> findBranchedApplicationId(Optional<String> branchName, String defaultApplicationId, Optional<AclPermission> permission) {
if (branchName.isEmpty()) {
if (!StringUtils.hasLength(defaultApplicationId)) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.APPLICATION_ID, defaultApplicationId));
}
return Mono.just(defaultApplicationId);
}
return repository.getApplicationByGitBranchAndDefaultApplicationId(defaultApplicationId, branchName.get(), permission)
.switchIfEmpty(Mono.error(
new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, defaultApplicationId + ", " + branchName))
)
.map(Application::getId);
}
/**
* As part of git sync feature a new application will be created for each branch with reference to main application
* feat/new-branch ----> new application in Appsmith

View File

@ -10,6 +10,7 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface DatasourceServiceCE extends CrudService<Datasource, String> {
@ -18,6 +19,8 @@ public interface DatasourceServiceCE extends CrudService<Datasource, String> {
Mono<Datasource> findByNameAndWorkspaceId(String name, String workspaceId, AclPermission permission);
Mono<Datasource> findByNameAndWorkspaceId(String name, String workspaceId, Optional<AclPermission> permission);
Mono<Datasource> findById(String id, AclPermission aclPermission);
Mono<Datasource> findById(String id);
@ -30,6 +33,8 @@ public interface DatasourceServiceCE extends CrudService<Datasource, String> {
Flux<Datasource> findAllByWorkspaceId(String workspaceId, AclPermission readDatasources);
Flux<Datasource> findAllByWorkspaceId(String workspaceId, Optional<AclPermission> readDatasources);
Flux<Datasource> saveAll(List<Datasource> datasourceList);
Mono<Datasource> populateHintMessages(Datasource datasource);
@ -38,4 +43,6 @@ public interface DatasourceServiceCE extends CrudService<Datasource, String> {
Mono<Datasource> getValidDatasourceFromActionMono(ActionDTO actionDTO, AclPermission aclPermission);
Mono<Datasource> createWithoutPermissions(Datasource datasource);
}

View File

@ -55,6 +55,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNestedNonNullProperties;
@ -107,6 +108,15 @@ public class DatasourceServiceCEImpl extends BaseService<DatasourceRepository, D
@Override
public Mono<Datasource> create(@NotNull Datasource datasource) {
return createEx(datasource, Optional.of(workspacePermission.getDatasourceCreatePermission()));
}
@Override
public Mono<Datasource> createWithoutPermissions(Datasource datasource) {
return createEx(datasource, Optional.empty());
}
private Mono<Datasource> createEx(@NotNull Datasource datasource, Optional<AclPermission> permission) {
String workspaceId = datasource.getWorkspaceId();
if (workspaceId == null) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.WORKSPACE_ID));
@ -131,7 +141,7 @@ public class DatasourceServiceCEImpl extends BaseService<DatasourceRepository, D
Mono<Datasource> datasourceWithPoliciesMono = datasourceMono
.flatMap(datasource1 -> {
Mono<User> userMono = sessionUserService.getCurrentUser();
return generateAndSetDatasourcePolicies(userMono, datasource1);
return generateAndSetDatasourcePolicies(userMono, datasource1, permission);
});
return datasourceWithPoliciesMono
@ -143,10 +153,11 @@ public class DatasourceServiceCEImpl extends BaseService<DatasourceRepository, D
.flatMap(repository::setUserPermissionsInObject);
}
private Mono<Datasource> generateAndSetDatasourcePolicies(Mono<User> userMono, Datasource datasource) {
private Mono<Datasource> generateAndSetDatasourcePolicies(Mono<User> userMono, Datasource datasource, Optional<AclPermission> permission) {
return userMono
.flatMap(user -> {
Mono<Workspace> workspaceMono = workspaceService.findById(datasource.getWorkspaceId(), workspacePermission.getDatasourceCreatePermission())
Mono<Workspace> workspaceMono = workspaceService.findById(datasource.getWorkspaceId(), permission)
.log()
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.WORKSPACE, datasource.getWorkspaceId())));
return workspaceMono.map(workspace -> {
@ -390,6 +401,11 @@ public class DatasourceServiceCEImpl extends BaseService<DatasourceRepository, D
return repository.findByNameAndWorkspaceId(name, workspaceId, permission);
}
@Override
public Mono<Datasource> findByNameAndWorkspaceId(String name, String workspaceId, Optional<AclPermission> permission) {
return repository.findByNameAndWorkspaceId(name, workspaceId, permission);
}
@Override
public Mono<Datasource> findById(String id, AclPermission aclPermission) {
return repository.findById(id, aclPermission);
@ -435,6 +451,12 @@ public class DatasourceServiceCEImpl extends BaseService<DatasourceRepository, D
.flatMap(this::populateHintMessages);
}
@Override
public Flux<Datasource> findAllByWorkspaceId(String workspaceId, Optional<AclPermission> permission) {
return repository.findAllByWorkspaceId(workspaceId, permission)
.flatMap(this::populateHintMessages);
}
@Override
public Flux<Datasource> saveAll(List<Datasource> datasourceList) {
datasourceList

View File

@ -9,6 +9,7 @@ import com.appsmith.external.dtos.MergeStatusDTO;
import com.appsmith.external.git.GitExecutor;
import com.appsmith.external.models.Datasource;
import com.appsmith.git.service.GitExecutorImpl;
import com.appsmith.server.acl.AclPermission;
import com.appsmith.server.configurations.EmailConfig;
import com.appsmith.server.constants.Assets;
import com.appsmith.server.constants.Entity;
@ -24,6 +25,7 @@ import com.appsmith.server.domains.GitDeployKeys;
import com.appsmith.server.domains.GitProfile;
import com.appsmith.server.domains.Plugin;
import com.appsmith.server.domains.UserData;
import com.appsmith.server.domains.Workspace;
import com.appsmith.server.dtos.ApplicationImportDTO;
import com.appsmith.server.dtos.GitCommitDTO;
import com.appsmith.server.dtos.GitConnectDTO;
@ -51,6 +53,7 @@ import com.appsmith.server.services.PluginService;
import com.appsmith.server.services.SessionUserService;
import com.appsmith.server.services.UserDataService;
import com.appsmith.server.services.UserService;
import com.appsmith.server.services.WorkspaceService;
import com.appsmith.server.solutions.ActionPermission;
import com.appsmith.server.solutions.ApplicationPermission;
import com.appsmith.server.solutions.DatasourcePermission;
@ -134,6 +137,7 @@ public class GitServiceCEImpl implements GitServiceCE {
private final ApplicationPermission applicationPermission;
private final PagePermission pagePermission;
private final ActionPermission actionPermission;
private final WorkspaceService workspaceService;
@Override
public Mono<Application> updateGitMetadata(String applicationId, GitApplicationMetadata gitApplicationMetadata) {
@ -367,9 +371,8 @@ public class GitServiceCEImpl implements GitServiceCE {
updateProfiles.put(DEFAULT, gitProfile);
}
UserData update = new UserData();
update.setGitProfiles(updateProfiles);
return userDataService.update(userData.getUserId(), update);
userData.setGitProfiles(updateProfiles);
return userDataService.updateForCurrentUser(userData);
});
}
return Mono.just(userData);
@ -1044,14 +1047,14 @@ public class GitServiceCEImpl implements GitServiceCE {
// Update all the resources to replace defaultResource Ids with the resource Ids as branchName
// will be deleted
Flux.fromIterable(application.getPages())
.flatMap(page -> newPageService.findById(page.getId(), pagePermission.getEditPermission()))
.flatMap(page -> newPageService.findById(page.getId(), Optional.empty()))
.map(newPage -> {
newPage.setDefaultResources(null);
return createDefaultIdsOrUpdateWithGivenResourceIds(newPage, null);
})
.collectList()
.flatMapMany(newPageService::saveAll)
.flatMap(newPage -> newActionService.findByPageId(newPage.getId(), actionPermission.getEditPermission())
.flatMap(newPage -> newActionService.findByPageId(newPage.getId(), Optional.empty())
.map(newAction -> {
newAction.setDefaultResources(null);
if (newAction.getUnpublishedAction() != null) {
@ -1831,9 +1834,12 @@ public class GitServiceCEImpl implements GitServiceCE {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, "Invalid workspace id"));
}
Mono<Workspace> workspaceMono = workspaceService.findById(workspaceId, AclPermission.WORKSPACE_CREATE_APPLICATION)
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.WORKSPACE, workspaceId)));
final String repoName = GitUtils.getRepoName(gitConnectDTO.getRemoteUrl());
Mono<Boolean> isPrivateRepoMono = GitUtils.isRepoPrivate(GitUtils.convertSshUrlToBrowserSupportedUrl(gitConnectDTO.getRemoteUrl())).cache();
Mono<ApplicationImportDTO> importedApplicationMono = getSSHKeyForCurrentUser()
Mono<ApplicationImportDTO> importedApplicationMono = workspaceMono.then(getSSHKeyForCurrentUser())
.zipWith(isPrivateRepoMono)
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION,
"Unable to find git configuration for logged-in user. Please contact Appsmith team for support")))

View File

@ -18,6 +18,7 @@ import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
public interface NewActionServiceCE extends CrudService<NewAction, String> {
@ -58,10 +59,14 @@ public interface NewActionServiceCE extends CrudService<NewAction, String> {
Flux<NewAction> findByPageId(String pageId, AclPermission permission);
Flux<NewAction> findByPageId(String pageId, Optional<AclPermission> permission);
Flux<NewAction> findByPageIdAndViewMode(String pageId, Boolean viewMode, AclPermission permission);
Flux<NewAction> findAllByApplicationIdAndViewMode(String applicationId, Boolean viewMode, AclPermission permission, Sort sort);
Flux<NewAction> findAllByApplicationIdAndViewMode(String applicationId, Boolean viewMode, Optional<AclPermission> permission, Optional<Sort> sort);
Flux<ActionViewDTO> getActionsForViewMode(String applicationId);
Flux<ActionViewDTO> getActionsForViewMode(String defaultApplicationId, String branchName);

View File

@ -1463,6 +1463,12 @@ public class NewActionServiceCEImpl extends BaseService<NewActionRepository, New
return repository.findByPageId(pageId, permission)
.flatMap(this::sanitizeAction);
}
@Override
public Flux<NewAction> findByPageId(String pageId, Optional<AclPermission> permission) {
return repository.findByPageId(pageId, permission)
.flatMap(this::sanitizeAction);
}
@Override
public Flux<NewAction> findByPageIdAndViewMode(String pageId, Boolean viewMode, AclPermission permission) {
@ -1489,6 +1495,25 @@ public class NewActionServiceCEImpl extends BaseService<NewActionRepository, New
.flatMap(this::sanitizeAction);
}
@Override
public Flux<NewAction> findAllByApplicationIdAndViewMode(String applicationId, Boolean viewMode, Optional<AclPermission> permission, Optional<Sort> sort) {
return repository.findByApplicationId(applicationId, permission, sort)
// In case of view mode being true, filter out all the actions which haven't been published
.flatMap(action -> {
if (Boolean.TRUE.equals(viewMode)) {
// In case we are trying to fetch published actions but this action has not been published, do not return
if (action.getPublishedAction() == null) {
return Mono.empty();
}
}
// No need to handle the edge case of unpublished action not being present. This is not possible because
// every created action starts from an unpublishedAction state.
return Mono.just(action);
})
.flatMap(this::sanitizeAction);
}
@Override
public Flux<ActionViewDTO> getActionsForViewMode(String defaultApplicationId, String branchName) {
return applicationService.findBranchedApplicationId(branchName, defaultApplicationId, applicationPermission.getReadPermission())

View File

@ -11,6 +11,7 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Optional;
public interface NewPageServiceCE extends CrudService<NewPage, String> {
@ -18,12 +19,16 @@ public interface NewPageServiceCE extends CrudService<NewPage, String> {
Mono<NewPage> findById(String pageId, AclPermission aclPermission);
Mono<NewPage> findById(String pageId, Optional<AclPermission> aclPermission);
Mono<PageDTO> findPageById(String pageId, AclPermission aclPermission, Boolean view);
Flux<PageDTO> findByApplicationId(String applicationId, AclPermission permission, Boolean view);
Flux<NewPage> findNewPagesByApplicationId(String applicationId, AclPermission permission);
Flux<NewPage> findNewPagesByApplicationId(String applicationId, Optional<AclPermission> permission);
Mono<PageDTO> saveUnpublishedPage(PageDTO page);
Mono<PageDTO> createDefault(PageDTO object);
@ -65,6 +70,8 @@ public interface NewPageServiceCE extends CrudService<NewPage, String> {
Mono<NewPage> archiveById(String id);
Mono<NewPage> archiveWithoutPermissionById(String id);
Flux<NewPage> saveAll(List<NewPage> pages);
Mono<String> getNameByPageId(String pageId, boolean isPublishedName);
@ -77,5 +84,7 @@ public interface NewPageServiceCE extends CrudService<NewPage, String> {
Mono<NewPage> findByGitSyncIdAndDefaultApplicationId(String defaultApplicationId, String gitSyncId, AclPermission permission);
Mono<NewPage> findByGitSyncIdAndDefaultApplicationId(String defaultApplicationId, String gitSyncId, Optional<AclPermission> permission);
Flux<NewPage> findPageSlugsByApplicationIds(List<String> applicationIds, AclPermission aclPermission);
}

View File

@ -42,6 +42,7 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -124,6 +125,11 @@ public class NewPageServiceCEImpl extends BaseService<NewPageRepository, NewPage
.flatMap(page -> getPageByViewMode(page, view));
}
@Override
public Mono<NewPage> findById(String pageId, Optional<AclPermission> aclPermission) {
return repository.findById(pageId, aclPermission);
}
@Override
public Flux<PageDTO> findByApplicationId(String applicationId, AclPermission permission, Boolean view) {
return findNewPagesByApplicationId(applicationId, permission)
@ -446,6 +452,11 @@ public class NewPageServiceCEImpl extends BaseService<NewPageRepository, NewPage
return repository.findByApplicationId(applicationId, permission);
}
@Override
public Flux<NewPage> findNewPagesByApplicationId(String applicationId, Optional<AclPermission> permission) {
return repository.findByApplicationId(applicationId, permission);
}
@Override
public Mono<List<NewPage>> archivePagesByApplicationId(String applicationId, AclPermission permission) {
return findNewPagesByApplicationId(applicationId, permission)
@ -508,9 +519,18 @@ public class NewPageServiceCEImpl extends BaseService<NewPageRepository, NewPage
return repository.archive(page);
}
@Override
public Mono<NewPage> archiveWithoutPermissionById(String id) {
return archiveByIdEx(id, Optional.empty());
}
@Override
public Mono<NewPage> archiveById(String id) {
Mono<NewPage> pageMono = this.findById(id, pagePermission.getDeletePermission())
return archiveByIdEx(id, Optional.of(pagePermission.getDeletePermission()));
}
public Mono<NewPage> archiveByIdEx(String id, Optional<AclPermission> permission) {
Mono<NewPage> pageMono = this.findById(id, permission)
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE_ID, id)))
.cache();
@ -593,6 +613,11 @@ public class NewPageServiceCEImpl extends BaseService<NewPageRepository, NewPage
return repository.findByGitSyncIdAndDefaultApplicationId(defaultApplicationId, gitSyncId, permission);
}
@Override
public Mono<NewPage> findByGitSyncIdAndDefaultApplicationId(String defaultApplicationId, String gitSyncId, Optional<AclPermission> permission) {
return repository.findByGitSyncIdAndDefaultApplicationId(defaultApplicationId, gitSyncId, permission);
}
@Override
public Flux<NewPage> findPageSlugsByApplicationIds(List<String> applicationIds, AclPermission aclPermission) {
return repository.findSlugsByApplicationIds(applicationIds, aclPermission);

View File

@ -10,6 +10,7 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface WorkspaceServiceCE extends CrudService<Workspace, String> {
@ -24,6 +25,8 @@ public interface WorkspaceServiceCE extends CrudService<Workspace, String> {
Mono<Workspace> findById(String id, AclPermission permission);
Mono<Workspace> findById(String id, Optional<AclPermission> permission);
Mono<Workspace> save(Workspace workspace);
Mono<Workspace> findByIdAndPluginsPluginId(String workspaceId, String pluginId);

View File

@ -51,6 +51,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@ -467,6 +468,11 @@ public class WorkspaceServiceCEImpl extends BaseService<WorkspaceRepository, Wor
return repository.findById(id, permission);
}
@Override
public Mono<Workspace> findById(String id, Optional<AclPermission> permission) {
return repository.findById(id, permission);
}
@Override
public Mono<Workspace> save(Workspace workspace) {
if (StringUtils.hasLength(workspace.getName())) {

View File

@ -56,7 +56,7 @@ public class ImportExportApplicationServiceImplV2 extends ImportExportApplicatio
super(datasourceService, sessionUserService, newActionRepository, datasourceRepository, pluginRepository,
workspaceService, applicationService, newPageService, applicationPageService, newPageRepository,
newActionService, sequenceService, examplesWorkspaceCloner, actionCollectionRepository,
actionCollectionService, themeService, policyUtils, analyticsService, datasourcePermission,
actionCollectionService, themeService, analyticsService, datasourcePermission,
workspacePermission, applicationPermission, pagePermission, actionPermission);
}
}

View File

@ -36,7 +36,6 @@ import com.appsmith.server.dtos.PageDTO;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import com.appsmith.server.helpers.DefaultResourcesUtils;
import com.appsmith.server.helpers.PolicyUtils;
import com.appsmith.server.helpers.TextUtils;
import com.appsmith.server.migrations.ApplicationVersion;
import com.appsmith.server.migrations.JsonSchemaMigration;
@ -69,7 +68,7 @@ import com.google.gson.reflect.TypeToken;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.dao.DuplicateKeyException;
@ -90,14 +89,11 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNestedNonNullProperties;
import static com.appsmith.server.acl.AclPermission.MANAGE_ACTIONS;
import static com.appsmith.server.acl.AclPermission.MANAGE_PAGES;
import static com.appsmith.server.acl.AclPermission.READ_ACTIONS;
import static com.appsmith.server.acl.AclPermission.READ_PAGES;
import static com.appsmith.server.acl.AclPermission.READ_THEMES;
import static com.appsmith.server.constants.ResourceModes.EDIT;
import static com.appsmith.server.constants.ResourceModes.VIEW;
@ -124,7 +120,6 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
private final ActionCollectionRepository actionCollectionRepository;
private final ActionCollectionService actionCollectionService;
private final ThemeService themeService;
private final PolicyUtils policyUtils;
private final AnalyticsService analyticsService;
private final DatasourcePermission datasourcePermission;
private final WorkspacePermission workspacePermission;
@ -240,9 +235,11 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
applicationJson.setExportedApplication(application);
Set<String> dbNamesUsedInActions = new HashSet<>();
Flux<NewPage> pageFlux = TRUE.equals(application.getExportWithConfiguration())
? newPageRepository.findByApplicationId(applicationId, pagePermission.getReadPermission())
: newPageRepository.findByApplicationId(applicationId, pagePermission.getEditPermission());
Optional<AclPermission> optionalPermission = isGitSync ? Optional.empty() :
TRUE.equals(application.getExportWithConfiguration())
? Optional.of(pagePermission.getReadPermission())
: Optional.of(pagePermission.getEditPermission());
Flux<NewPage> pageFlux = newPageRepository.findByApplicationId(applicationId, optionalPermission);
return pageFlux
.collectList()
@ -289,10 +286,13 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
put(FieldName.PAGE_LIST, updatedPageSet);
}});
Flux<Datasource> datasourceFlux = TRUE.equals(application.getExportWithConfiguration())
? datasourceRepository.findAllByWorkspaceId(workspaceId, datasourcePermission.getReadPermission())
: datasourceRepository.findAllByWorkspaceId(workspaceId, datasourcePermission.getEditPermission());
Optional<AclPermission> optionalPermission3 = isGitSync ? Optional.empty()
: TRUE.equals(application.getExportWithConfiguration())
? Optional.of(datasourcePermission.getReadPermission())
: Optional.of(datasourcePermission.getEditPermission());
Flux<Datasource> datasourceFlux =
datasourceRepository.findAllByWorkspaceId(workspaceId, optionalPermission3);
return datasourceFlux.collectList();
})
.flatMapMany(datasourceList -> {
@ -300,9 +300,12 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
datasourceIdToNameMap.put(datasource.getId(), datasource.getName()));
applicationJson.setDatasourceList(datasourceList);
Flux<ActionCollection> actionCollectionFlux = TRUE.equals(application.getExportWithConfiguration())
? actionCollectionRepository.findByApplicationId(applicationId, actionPermission.getReadPermission(), null)
: actionCollectionRepository.findByApplicationId(applicationId, actionPermission.getEditPermission(), null);
Optional<AclPermission> optionalPermission1 = isGitSync ? Optional.empty() :
TRUE.equals(application.getExportWithConfiguration())
? Optional.of(actionPermission.getReadPermission())
: Optional.of(actionPermission.getEditPermission());
Flux<ActionCollection> actionCollectionFlux =
actionCollectionRepository.findByApplicationId(applicationId, optionalPermission1, Optional.empty());
return actionCollectionFlux;
})
.map(actionCollection -> {
@ -356,10 +359,13 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
applicationJson.setActionCollectionList(actionCollections);
applicationJson.getUpdatedResources().put(FieldName.ACTION_COLLECTION_LIST, updatedActionCollectionSet);
Flux<NewAction> actionFlux = TRUE.equals(application.getExportWithConfiguration())
? newActionRepository.findByApplicationId(applicationId, actionPermission.getReadPermission(), null)
: newActionRepository.findByApplicationId(applicationId, actionPermission.getEditPermission(), null);
Optional<AclPermission> optionalPermission2 = isGitSync ? Optional.empty()
: TRUE.equals(application.getExportWithConfiguration())
? Optional.of(actionPermission.getReadPermission())
: Optional.of(actionPermission.getEditPermission());
Flux<NewAction> actionFlux =
newActionRepository.findByApplicationId(applicationId, optionalPermission2, Optional.empty());
return actionFlux;
})
.map(newAction -> {
@ -602,14 +608,12 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
* @return saved application in DB
*/
public Mono<Application> importApplicationInWorkspace(String workspaceId, ApplicationJson importedDoc) {
return importApplicationInWorkspace(workspaceId, importedDoc, null, null);
return importApplicationInWorkspace(workspaceId, importedDoc, null, null, false, false);
}
public Mono<Application> importApplicationInWorkspace(String workspaceId,
ApplicationJson applicationJson,
String applicationId,
String branchName) {
return importApplicationInWorkspace(workspaceId, applicationJson, applicationId, branchName, false);
@Override
public Mono<Application> importApplicationInWorkspace(String workspaceId, ApplicationJson importedDoc, String applicationId, String branchName) {
return importApplicationInWorkspace(workspaceId, importedDoc, applicationId, branchName, false, !StringUtils.isEmpty(branchName));
}
/**
@ -647,7 +651,8 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
ApplicationJson applicationJson,
String applicationId,
String branchName,
boolean appendToApp) {
boolean appendToApp,
boolean isGitSync) {
/*
1. Migrate resource to latest schema
2. Fetch workspace by id
@ -686,7 +691,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
Mono<User> currUserMono = sessionUserService.getCurrentUser().cache();
final Flux<Datasource> existingDatasourceFlux = datasourceRepository
.findAllByWorkspaceId(workspaceId, datasourcePermission.getEditPermission())
.findAllByWorkspaceId(workspaceId, isGitSync ? Optional.empty() : Optional.of(datasourcePermission.getEditPermission()))
.cache();
assert importedApplication != null : "Received invalid application object!";
@ -708,7 +713,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
pluginMap.put(pluginReference, plugin.getId());
return plugin;
})
.then(workspaceService.findById(workspaceId, workspacePermission.getApplicationCreatePermission()))
.then(workspaceService.findById(workspaceId, isGitSync ? Optional.empty() : Optional.of(workspacePermission.getApplicationCreatePermission())))
.switchIfEmpty(Mono.error(
new AppsmithException(AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.WORKSPACE, workspaceId))
)
@ -802,7 +807,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
importedApplication.setWorkspaceId(workspaceId);
// Application Id will be present for GIT sync
if (!StringUtils.isEmpty(applicationId)) {
return applicationService.findById(applicationId, applicationPermission.getEditPermission())
return applicationService.findById(applicationId, Optional.empty())
.switchIfEmpty(
Mono.error(new AppsmithException(
AppsmithError.ACL_NO_RESOURCE_FOUND,
@ -870,7 +875,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
// For git-sync this will not be empty
Mono<List<NewPage>> existingPagesMono = newPageService
.findNewPagesByApplicationId(importedApplication.getId(), pagePermission.getEditPermission())
.findNewPagesByApplicationId(importedApplication.getId(), Optional.empty())
.collectList()
.cache();
@ -1003,8 +1008,8 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
// Delete the pages which were removed during git merge operation
// This does not apply to the traditional import via file approach
return Flux.fromIterable(invalidPageIds)
.flatMap(applicationPageService::deleteUnpublishedPage)
.flatMap(page -> newPageService.archiveById(page.getId())
.flatMap(applicationPageService::deleteWithoutPermissionUnpublishedPage)
.flatMap(page -> newPageService.archiveWithoutPermissionById(page.getId())
.onErrorResume(e -> {
log.debug("Unable to archive page {} with error {}", page.getId(), e.getMessage());
return Mono.empty();
@ -1117,7 +1122,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
}
}
return Flux.fromIterable(invalidCollectionIds)
.flatMap(collectionId -> actionCollectionService.deleteUnpublishedActionCollection(collectionId)
.flatMap(collectionId -> actionCollectionService.deleteWithoutPermissionUnpublishedActionCollection(collectionId)
// return an empty collection so that the filter can remove it from the list
.onErrorResume(throwable -> {
log.debug("Failed to delete collection with id {} during import", collectionId);
@ -1136,7 +1141,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
// Don't update gitAuth as we are using @Encrypted for private key
importedApplication.setGitApplicationMetadata(null);
// Map layoutOnLoadActions ids with relevant actions
return newPageService.findNewPagesByApplicationId(importedApplication.getId(), pagePermission.getEditPermission())
return newPageService.findNewPagesByApplicationId(importedApplication.getId(), Optional.empty())
.flatMap(newPage -> {
if (newPage.getDefaultResources() != null) {
newPage.getDefaultResources().setBranchName(branchName);
@ -1156,7 +1161,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
stopwatch.stopAndLogTimeInMillis();
final Map<String, Object> data = Map.of(
FieldName.APPLICATION_ID, application.getId(),
FieldName.ORGANIZATION_ID, application.getWorkspaceId(),
FieldName.WORKSPACE_ID, application.getWorkspaceId(),
"pageCount", applicationJson.getPageList().size(),
"actionCount", applicationJson.getActionList().size(),
"JSObjectCount", applicationJson.getActionCollectionList().size(),
@ -1288,7 +1293,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
return newPageService.save(existingPage);
} else if (application.getGitApplicationMetadata() != null) {
final String defaultApplicationId = application.getGitApplicationMetadata().getDefaultApplicationId();
return newPageService.findByGitSyncIdAndDefaultApplicationId(defaultApplicationId, newPage.getGitSyncId(), pagePermission.getEditPermission())
return newPageService.findByGitSyncIdAndDefaultApplicationId(defaultApplicationId, newPage.getGitSyncId(), Optional.empty())
.switchIfEmpty(Mono.defer(() -> {
// This is the first page we are saving with given gitSyncId in this instance
DefaultResources defaultResources = new DefaultResources();
@ -1408,7 +1413,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
return newActionService.save(existingAction);
} else if (importedApplication.getGitApplicationMetadata() != null) {
final String defaultApplicationId = importedApplication.getGitApplicationMetadata().getDefaultApplicationId();
return newActionRepository.findByGitSyncIdAndDefaultApplicationId(defaultApplicationId, newAction.getGitSyncId(), actionPermission.getEditPermission())
return newActionRepository.findByGitSyncIdAndDefaultApplicationId(defaultApplicationId, newAction.getGitSyncId(), Optional.empty())
.switchIfEmpty(Mono.defer(() -> {
// This is the first page we are saving with given gitSyncId in this instance
DefaultResources defaultResources = new DefaultResources();
@ -1564,7 +1569,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
);
} else if (importedApplication.getGitApplicationMetadata() != null) {
final String defaultApplicationId = importedApplication.getGitApplicationMetadata().getDefaultApplicationId();
return actionCollectionRepository.findByGitSyncIdAndDefaultApplicationId(defaultApplicationId, actionCollection.getGitSyncId(), actionPermission.getEditPermission())
return actionCollectionRepository.findByGitSyncIdAndDefaultApplicationId(defaultApplicationId, actionCollection.getGitSyncId(), Optional.empty())
.switchIfEmpty(Mono.defer(() -> {
// This is the first page we are saving with given gitSyncId in this instance
DefaultResources defaultResources = new DefaultResources();
@ -1635,7 +1640,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
actionIds.addAll(unpublishedActionIdToCollectionIdMap.keySet());
actionIds.addAll(publishedActionIdToCollectionIdMap.keySet());
return Flux.fromIterable(actionIds)
.flatMap(actionId -> newActionRepository.findById(actionId, actionPermission.getEditPermission()))
.flatMap(actionId -> newActionRepository.findById(actionId, Optional.empty()))
.map(newAction -> {
// Update collectionId and defaultCollectionIds in actionDTOs
ActionDTO unpublishedAction = newAction.getUnpublishedAction();
@ -1906,7 +1911,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
// No matching existing datasource found, so create a new one.
datasource.setIsConfigured(datasourceConfig != null && datasourceConfig.getAuthentication() != null);
return datasourceService
.findByNameAndWorkspaceId(datasource.getName(), workspaceId, datasourcePermission.getEditPermission())
.findByNameAndWorkspaceId(datasource.getName(), workspaceId, Optional.empty())
.flatMap(duplicateNameDatasource ->
getUniqueSuffixForDuplicateNameEntity(duplicateNameDatasource, workspaceId)
)
@ -1914,7 +1919,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
datasource.setName(datasource.getName() + suffix);
return datasource;
})
.then(datasourceService.create(datasource));
.then(datasourceService.createWithoutPermissions(datasource));
}));
}
@ -2000,8 +2005,8 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
public Mono<List<Datasource>> findDatasourceByApplicationId(String applicationId, String workspaceId) {
// TODO: Investigate further why datasourcePermission.getReadPermission() is not being used.
Mono<List<Datasource>> listMono = datasourceService.findAllByWorkspaceId(workspaceId, datasourcePermission.getEditPermission()).collectList();
return newActionService.findAllByApplicationIdAndViewMode(applicationId, false, actionPermission.getReadPermission(), null)
Mono<List<Datasource>> listMono = datasourceService.findAllByWorkspaceId(workspaceId, Optional.empty()).collectList();
return newActionService.findAllByApplicationIdAndViewMode(applicationId, false, Optional.empty(), Optional.empty())
.collectList()
.zipWith(listMono)
.flatMap(objects -> {
@ -2107,7 +2112,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
applicationJson.setActionCollectionList(importedActionCollectionList);
}
return importApplicationInWorkspace(workspaceId, applicationJson, applicationId, branchName, true);
return importApplicationInWorkspace(workspaceId, applicationJson, applicationId, branchName, true, !StringUtils.isEmpty(branchName));
}
private Mono<Map<String, String>> updateNewPagesBeforeMerge(Mono<List<NewPage>> existingPagesMono, List<NewPage> newPagesList) {
@ -2150,7 +2155,7 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli
*/
private Mono<Application> sendImportExportApplicationAnalyticsEvent(String applicationId, AnalyticsEvents event) {
return applicationService.findById(applicationId, applicationPermission.getReadPermission())
return applicationService.findById(applicationId, Optional.empty())
.flatMap(application -> {
return Mono.zip(Mono.just(application), workspaceService.getById(application.getWorkspaceId()));
})

View File

@ -1,6 +1,7 @@
package com.appsmith.server.services;
import com.appsmith.external.models.DefaultResources;
import com.appsmith.server.acl.AclPermission;
import com.appsmith.server.acl.PolicyGenerator;
import com.appsmith.server.constants.FieldName;
import com.appsmith.server.domains.ActionCollection;
@ -53,6 +54,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -213,7 +215,7 @@ public class ActionCollectionServiceImplTest {
final JsonNode jsonNode = objectMapper.readValue(mockObjects, JsonNode.class);
final NewPage newPage = objectMapper.convertValue(jsonNode.get("newPage"), NewPage.class);
Mockito
.when(newPageService.findById(Mockito.any(), Mockito.any()))
.when(newPageService.findById(Mockito.any(), Mockito.<AclPermission>any()))
.thenReturn(Mono.just(newPage));
Mockito
.when(layoutActionService.isNameAllowed(Mockito.any(), Mockito.any(), Mockito.any()))
@ -256,7 +258,7 @@ public class ActionCollectionServiceImplTest {
final NewPage newPage = objectMapper.convertValue(jsonNode.get("newPage"), NewPage.class);
Mockito
.when(newPageService.findById(Mockito.any(), Mockito.any()))
.when(newPageService.findById(Mockito.any(), Mockito.<AclPermission>any()))
.thenReturn(Mono.just(newPage));
Mockito
.when(layoutActionService.isNameAllowed(Mockito.any(), Mockito.any(), Mockito.any()))
@ -329,7 +331,7 @@ public class ActionCollectionServiceImplTest {
final NewPage newPage = objectMapper.convertValue(jsonNode.get("newPage"), NewPage.class);
Mockito
.when(newPageService.findById(Mockito.any(), Mockito.any()))
.when(newPageService.findById(Mockito.any(), Mockito.<AclPermission>any()))
.thenReturn(Mono.just(newPage));
Mockito
.when(layoutActionService.isNameAllowed(Mockito.any(), Mockito.any(), Mockito.any()))
@ -425,7 +427,7 @@ public class ActionCollectionServiceImplTest {
final NewPage newPage = objectMapper.convertValue(jsonNode.get("newPage"), NewPage.class);
Mockito
.when(actionCollectionRepository.findById(Mockito.anyString(), Mockito.any()))
.when(actionCollectionRepository.findById(Mockito.anyString(), Mockito.<AclPermission>any()))
.thenReturn(Mono.empty());
Mockito
@ -436,7 +438,7 @@ public class ActionCollectionServiceImplTest {
Mockito
.when(newPageService
.findById(Mockito.any(), Mockito.any()))
.findById(Mockito.any(), Mockito.<AclPermission>any()))
.thenReturn(Mono.just(newPage));
final Mono<ActionCollectionDTO> actionCollectionDTOMono =
@ -490,7 +492,7 @@ public class ActionCollectionServiceImplTest {
.thenReturn(Mono.just((Mockito.mock(UpdateResult.class))));
Mockito
.when(actionCollectionRepository.findById(Mockito.anyString(), Mockito.any()))
.when(actionCollectionRepository.findById(Mockito.anyString(), Mockito.<AclPermission>any()))
.thenReturn(Mono.just(actionCollection));
Mockito
@ -516,7 +518,7 @@ public class ActionCollectionServiceImplTest {
Mockito
.when(newPageService
.findById(Mockito.any(), Mockito.any()))
.findById(Mockito.any(), Mockito.<AclPermission>any()))
.thenReturn(Mono.just(newPage));
Mockito.when(actionCollectionRepository.setUserPermissionsInObject(Mockito.any()))
@ -552,7 +554,7 @@ public class ActionCollectionServiceImplTest {
@Test
public void testDeleteUnpublishedActionCollection_withInvalidId_throwsError() {
Mockito
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.any()))
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<Optional<AclPermission>>any()))
.thenReturn(Mono.empty());
final Mono<ActionCollectionDTO> actionCollectionMono =
@ -580,7 +582,7 @@ public class ActionCollectionServiceImplTest {
Instant deletedAt = Instant.now();
Mockito
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.any()))
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<Optional<AclPermission>>any()))
.thenReturn(Mono.just(actionCollection));
Mockito
@ -614,7 +616,7 @@ public class ActionCollectionServiceImplTest {
Instant deletedAt = Instant.now();
Mockito
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.any()))
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<Optional<AclPermission>>any()))
.thenReturn(Mono.just(actionCollection));
Mockito
@ -651,7 +653,7 @@ public class ActionCollectionServiceImplTest {
actionCollection.getUnpublishedCollection().setDefaultResources(setDefaultResources(actionCollection.getUnpublishedCollection()));
Mockito
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.any()))
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<Optional<AclPermission>>any()))
.thenReturn(Mono.just(actionCollection));
Mockito
@ -684,7 +686,7 @@ public class ActionCollectionServiceImplTest {
actionCollection.getUnpublishedCollection().setDefaultResources(setDefaultResources(actionCollection.getUnpublishedCollection()));
Mockito
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.any()))
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<Optional<AclPermission>>any()))
.thenReturn(Mono.just(actionCollection));
Mockito
@ -783,7 +785,7 @@ public class ActionCollectionServiceImplTest {
.thenReturn(Mono.just(true));
Mockito
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.any()))
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<AclPermission>any()))
.thenReturn(Mono.just(oldActionCollection));
Mockito
@ -851,7 +853,7 @@ public class ActionCollectionServiceImplTest {
.thenReturn(Mono.just(true));
Mockito
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.any()))
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<AclPermission>any()))
.thenReturn(Mono.just(oldActionCollection));
Mockito
@ -919,7 +921,7 @@ public class ActionCollectionServiceImplTest {
action.setDefaultResources(actionResources);
Mockito
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.any()))
.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<AclPermission>any()))
.thenReturn(Mono.just(actionCollection));
Mockito
@ -959,7 +961,7 @@ public class ActionCollectionServiceImplTest {
.thenReturn(Mono.just(newPageDTO));
Mockito
.when(newPageService.findById(Mockito.any(), Mockito.any()))
.when(newPageService.findById(Mockito.any(), Mockito.<AclPermission>any()))
.thenReturn(Mono.just(newPage));
LayoutDTO layout = new LayoutDTO();

View File

@ -17,6 +17,7 @@ import com.appsmith.server.services.PluginService;
import com.appsmith.server.services.SessionUserService;
import com.appsmith.server.services.UserDataService;
import com.appsmith.server.services.UserService;
import com.appsmith.server.services.WorkspaceService;
import com.appsmith.server.solutions.ActionPermission;
import com.appsmith.server.solutions.ApplicationPermission;
import com.appsmith.server.solutions.DatasourcePermission;
@ -86,6 +87,8 @@ public class GitServiceCEImplTest {
PagePermission pagePermission;
@MockBean
ActionPermission actionPermission;
@MockBean
WorkspaceService workspaceService;
@BeforeEach
public void setup() {
@ -94,7 +97,7 @@ public class GitServiceCEImplTest {
newPageService, newActionService, actionCollectionService, gitFileUtils, importExportApplicationService,
gitExecutor, responseUtils, emailConfig, analyticsService, gitCloudServicesUtils, gitDeployKeysRepository,
datasourceService, pluginService, datasourcePermission, applicationPermission, pagePermission,
actionPermission
actionPermission, workspaceService
);
}