diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/User.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/User.java index c50230101f..b09886755b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/User.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/User.java @@ -110,6 +110,12 @@ public class User extends BaseDomain implements UserDetails, OidcUser { @JsonView(Views.Public.class) private String tenantId; + // Field to indicate if the user is system generated or not. Expected to be `true` for system generated users, null + // otherwise. + // e.g. AnonymousUser is created by the system migration during the first time startup. + @JsonView(Views.Internal.class) + Boolean isSystemGenerated; + // TODO: Populate these attributes for a user. Generally required for OAuth2 logins @Override @JsonView(Views.Public.class) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration037MarkAnonymousUserAsSystemGenerated.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration037MarkAnonymousUserAsSystemGenerated.java new file mode 100644 index 0000000000..4ef65c32ca --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration037MarkAnonymousUserAsSystemGenerated.java @@ -0,0 +1,43 @@ +package com.appsmith.server.migrations.db.ce; + +import com.appsmith.server.domains.QUser; +import com.appsmith.server.domains.User; +import com.mongodb.client.result.UpdateResult; +import io.mongock.api.annotations.ChangeUnit; +import io.mongock.api.annotations.Execution; +import io.mongock.api.annotations.RollbackExecution; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Update; + +import static com.appsmith.server.repositories.ce.BaseAppsmithRepositoryCEImpl.fieldName; +import static org.springframework.data.mongodb.core.query.Criteria.where; +import static org.springframework.data.mongodb.core.query.Query.query; + +@Slf4j +@ChangeUnit(order = "037", id = "mark-anonymous-user-as-system-generated", author = " ") +public class Migration037MarkAnonymousUserAsSystemGenerated { + private final MongoTemplate mongoTemplate; + + public Migration037MarkAnonymousUserAsSystemGenerated(MongoTemplate mongoTemplate) { + this.mongoTemplate = mongoTemplate; + } + + @RollbackExecution + public void rollbackExecution() {} + + @Execution + public void executeMigration() { + + final Update update = new Update(); + update.set(fieldName(QUser.user.isSystemGenerated), true); + try { + // We expect only 1 anonymous user to be present in the system, but we are using updateMulti to be safe. + UpdateResult result = mongoTemplate.updateMulti( + query(where(fieldName(QUser.user.isAnonymous)).is(true)), update, User.class); + log.info("Marked {} anonymous users as system generated", result.getModifiedCount()); + } catch (Exception e) { + log.error("Error while marking anonymous user as system generated", e); + } + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/UserRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/UserRepositoryCE.java index 421b2b7e69..e28e5a5bf0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/UserRepositoryCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/UserRepositoryCE.java @@ -11,7 +11,14 @@ public interface UserRepositoryCE extends BaseRepository, CustomUs Mono findByCaseInsensitiveEmail(String email); - Mono countByDeletedAtNull(); + /** + * This method returns the count of all users that are not deleted and are not system generated. + * + * @param excludeSystemGenerated If true, then the count of all users that are not deleted and are not system + * generated is returned. + * @return The count of all users that are not deleted and are not system generated. + */ + Mono countByDeletedAtIsNullAndIsSystemGeneratedIsNot(Boolean excludeSystemGenerated); Mono findByEmailAndTenantId(String email, String tenantId); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/PingScheduledTaskCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/PingScheduledTaskCEImpl.java index 6b4a920cb9..69df56eded 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/PingScheduledTaskCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/PingScheduledTaskCEImpl.java @@ -122,13 +122,19 @@ public class PingScheduledTaskCEImpl implements PingScheduledTaskCE { } Mono publicPermissionGroupIdMono = permissionGroupService.getPublicPermissionGroupId(); + + // Get the non-system generated active user count + Mono userCountMono = userRepository + .countByDeletedAtIsNullAndIsSystemGeneratedIsNot(true) + .defaultIfEmpty(0L); + Mono> nonDeletedObjectsCountMono = Mono.zip( workspaceRepository.countByDeletedAtNull().defaultIfEmpty(0L), applicationRepository.countByDeletedAtNull().defaultIfEmpty(0L), newPageRepository.countByDeletedAtNull().defaultIfEmpty(0L), newActionRepository.countByDeletedAtNull().defaultIfEmpty(0L), datasourceRepository.countByDeletedAtNull().defaultIfEmpty(0L), - userRepository.countByDeletedAtNull().defaultIfEmpty(0L)); + userCountMono); publicPermissionGroupIdMono .flatMap(publicPermissionGroupId -> Mono.zip(