chore: Dynamically fetch system generated users via DB query (#40323)
This commit is contained in:
parent
f7e8aada2e
commit
988537f805
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.appsmith.server.projections;
|
||||||
|
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
public record EmailOnly(@NonNull String email) {}
|
||||||
|
|
@ -3,17 +3,16 @@ package com.appsmith.server.repositories.ce;
|
||||||
import com.appsmith.server.domains.User;
|
import com.appsmith.server.domains.User;
|
||||||
import com.appsmith.server.repositories.AppsmithRepository;
|
import com.appsmith.server.repositories.AppsmithRepository;
|
||||||
import org.springframework.data.mongodb.core.query.UpdateDefinition;
|
import org.springframework.data.mongodb.core.query.UpdateDefinition;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public interface CustomUserRepositoryCE extends AppsmithRepository<User> {
|
public interface CustomUserRepositoryCE extends AppsmithRepository<User> {
|
||||||
|
|
||||||
Mono<User> findByEmailAndOrganizationId(String email, String organizationId);
|
Mono<User> findByEmailAndOrganizationId(String email, String organizationId);
|
||||||
|
|
||||||
Mono<Boolean> isUsersEmpty();
|
Mono<Boolean> isUsersEmpty();
|
||||||
|
|
||||||
Set<String> getSystemGeneratedUserEmails();
|
Flux<String> getSystemGeneratedUserEmails(String organizationId);
|
||||||
|
|
||||||
Mono<Integer> updateById(String id, UpdateDefinition updateObj);
|
Mono<Integer> updateById(String id, UpdateDefinition updateObj);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,15 @@ import com.appsmith.server.domains.User;
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
import com.appsmith.server.exceptions.AppsmithException;
|
import com.appsmith.server.exceptions.AppsmithException;
|
||||||
import com.appsmith.server.helpers.ce.bridge.Bridge;
|
import com.appsmith.server.helpers.ce.bridge.Bridge;
|
||||||
|
import com.appsmith.server.projections.EmailOnly;
|
||||||
import com.appsmith.server.projections.IdOnly;
|
import com.appsmith.server.projections.IdOnly;
|
||||||
import com.appsmith.server.repositories.BaseAppsmithRepositoryImpl;
|
import com.appsmith.server.repositories.BaseAppsmithRepositoryImpl;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.mongodb.core.query.UpdateDefinition;
|
import org.springframework.data.mongodb.core.query.UpdateDefinition;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import static com.appsmith.server.helpers.ce.bridge.Bridge.notExists;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class CustomUserRepositoryCEImpl extends BaseAppsmithRepositoryImpl<User> implements CustomUserRepositoryCE {
|
public class CustomUserRepositoryCEImpl extends BaseAppsmithRepositoryImpl<User> implements CustomUserRepositoryCE {
|
||||||
|
|
@ -25,7 +26,8 @@ public class CustomUserRepositoryCEImpl extends BaseAppsmithRepositoryImpl<User>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch minimal information from *a* user document in the database, limit to two documents, filter anonymousUser
|
* Fetch minimal information from *a* user document in the database, limit to two documents, filter system generated
|
||||||
|
* users.
|
||||||
* If no documents left return true otherwise return false.
|
* If no documents left return true otherwise return false.
|
||||||
*
|
*
|
||||||
* @return Boolean, indicated where there exists at least one user in the system or not.
|
* @return Boolean, indicated where there exists at least one user in the system or not.
|
||||||
|
|
@ -33,7 +35,8 @@ public class CustomUserRepositoryCEImpl extends BaseAppsmithRepositoryImpl<User>
|
||||||
@Override
|
@Override
|
||||||
public Mono<Boolean> isUsersEmpty() {
|
public Mono<Boolean> isUsersEmpty() {
|
||||||
return queryBuilder()
|
return queryBuilder()
|
||||||
.criteria(Bridge.notIn(User.Fields.email, getSystemGeneratedUserEmails()))
|
.criteria(Bridge.or(
|
||||||
|
notExists(User.Fields.isSystemGenerated), Bridge.isFalse(User.Fields.isSystemGenerated)))
|
||||||
.limit(1)
|
.limit(1)
|
||||||
.all(IdOnly.class)
|
.all(IdOnly.class)
|
||||||
.count()
|
.count()
|
||||||
|
|
@ -41,10 +44,12 @@ public class CustomUserRepositoryCEImpl extends BaseAppsmithRepositoryImpl<User>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getSystemGeneratedUserEmails() {
|
public Flux<String> getSystemGeneratedUserEmails(String organizationId) {
|
||||||
Set<String> systemGeneratedEmails = new HashSet<>();
|
return queryBuilder()
|
||||||
systemGeneratedEmails.add(FieldName.ANONYMOUS_USER);
|
.criteria(Bridge.equal(User.Fields.isSystemGenerated, true)
|
||||||
return systemGeneratedEmails;
|
.equal(User.Fields.organizationId, organizationId))
|
||||||
|
.all(EmailOnly.class)
|
||||||
|
.map(EmailOnly::email);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,128 @@
|
||||||
|
package com.appsmith.server.repositories.ce;
|
||||||
|
|
||||||
|
import com.appsmith.server.domains.Organization;
|
||||||
|
import com.appsmith.server.domains.User;
|
||||||
|
import com.appsmith.server.repositories.OrganizationRepository;
|
||||||
|
import com.appsmith.server.repositories.UserRepository;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
public class CustomUserRepositoryCEImplTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private OrganizationRepository organizationRepository;
|
||||||
|
|
||||||
|
private final List<User> savedUsers = new ArrayList<>();
|
||||||
|
private static final Set<String> PREDEFINED_SYSTEM_USERS = Set.of("anonymousUser");
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
this.savedUsers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void cleanUp() {
|
||||||
|
for (User savedUser : savedUsers) {
|
||||||
|
userRepository.deleteById(savedUser.getId()).block();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSystemGeneratedUserEmails_WhenSystemGeneratedUsersExist_ReturnsTheirEmails() {
|
||||||
|
String defaultOrgId = organizationRepository
|
||||||
|
.findBySlug("default")
|
||||||
|
.map(Organization::getId)
|
||||||
|
.block();
|
||||||
|
|
||||||
|
// Create an additional system-generated user
|
||||||
|
User systemUser = new User();
|
||||||
|
systemUser.setEmail("system@test.com");
|
||||||
|
systemUser.setIsSystemGenerated(true);
|
||||||
|
systemUser.setOrganizationId(defaultOrgId);
|
||||||
|
User savedSystemUser = userRepository.save(systemUser).block();
|
||||||
|
savedUsers.add(savedSystemUser);
|
||||||
|
|
||||||
|
// Create a non-system-generated user
|
||||||
|
User nonSystemUser = new User();
|
||||||
|
nonSystemUser.setEmail("non-system@test.com");
|
||||||
|
nonSystemUser.setIsSystemGenerated(false);
|
||||||
|
nonSystemUser.setOrganizationId(defaultOrgId);
|
||||||
|
User savedNonSystemUser = userRepository.save(nonSystemUser).block();
|
||||||
|
savedUsers.add(savedNonSystemUser);
|
||||||
|
|
||||||
|
// Test the method
|
||||||
|
Flux<String> systemGeneratedEmails = userRepository.getSystemGeneratedUserEmails(defaultOrgId);
|
||||||
|
|
||||||
|
StepVerifier.create(systemGeneratedEmails.collectList())
|
||||||
|
.assertNext(emails -> {
|
||||||
|
// Verify all predefined system users are present
|
||||||
|
assertThat(emails).containsAll(PREDEFINED_SYSTEM_USERS);
|
||||||
|
// Verify our test system user is present
|
||||||
|
assertThat(emails).contains("system@test.com");
|
||||||
|
// Verify non-system user is not present
|
||||||
|
assertThat(emails).doesNotContain("non-system@test.com");
|
||||||
|
// Verify total count is correct (predefined users + our test user)
|
||||||
|
assertThat(emails).hasSize(PREDEFINED_SYSTEM_USERS.size() + 1);
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSystemGeneratedUserEmails_WhenNoAdditionalSystemGeneratedUsersExist_ReturnsOnlyPredefinedUsers() {
|
||||||
|
String defaultOrgId = organizationRepository
|
||||||
|
.findBySlug("default")
|
||||||
|
.map(Organization::getId)
|
||||||
|
.block();
|
||||||
|
|
||||||
|
// Create only non-system-generated user
|
||||||
|
User nonSystemUser = new User();
|
||||||
|
nonSystemUser.setEmail("non-system@test.com");
|
||||||
|
nonSystemUser.setIsSystemGenerated(false);
|
||||||
|
nonSystemUser.setOrganizationId(defaultOrgId);
|
||||||
|
User savedNonSystemUser = userRepository.save(nonSystemUser).block();
|
||||||
|
savedUsers.add(savedNonSystemUser);
|
||||||
|
|
||||||
|
// Test the method
|
||||||
|
Flux<String> systemGeneratedEmails = userRepository.getSystemGeneratedUserEmails(defaultOrgId);
|
||||||
|
|
||||||
|
StepVerifier.create(systemGeneratedEmails.collectList())
|
||||||
|
.assertNext(emails -> {
|
||||||
|
// Verify only predefined system users are present
|
||||||
|
assertThat(emails).containsExactlyInAnyOrderElementsOf(PREDEFINED_SYSTEM_USERS);
|
||||||
|
// Verify non-system user is not present
|
||||||
|
assertThat(emails).doesNotContain("non-system@test.com");
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isUsersEmpty_WhenNonSystemUsersExist_ReturnsFalse() {
|
||||||
|
// Create a non-system-generated user
|
||||||
|
User nonSystemUser = new User();
|
||||||
|
nonSystemUser.setEmail("non-system@test.com");
|
||||||
|
User savedNonSystemUser = userRepository.save(nonSystemUser).block();
|
||||||
|
savedUsers.add(savedNonSystemUser);
|
||||||
|
|
||||||
|
// Test the method
|
||||||
|
StepVerifier.create(userRepository.isUsersEmpty())
|
||||||
|
.assertNext(isEmpty -> {
|
||||||
|
assertThat(isEmpty).isFalse();
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user