Fix Issue for removed user updating an entity (#22931)

* Fix Issue for removed user updating an entity

* Fix updatingUser resolution to use current updater instead of previous

---------

Co-authored-by: aji-aju <ajithprasad770@gmail.com>
Co-authored-by: Ajith Prasad <37380177+aji-aju@users.noreply.github.com>
This commit is contained in:
Mohit Yadav 2025-09-15 18:22:25 +05:30 committed by GitHub
parent 004aac5107
commit 4efb507a0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 82 additions and 3 deletions

View File

@ -530,6 +530,18 @@ public final class Entity {
return entity;
}
public static <T> T findEntityByNameOrNull(String entityType, String fqn, Include include) {
return findByNameOrNull(entityType, fqn, include);
}
/** Retrieve the entity using id from given entity reference and fields */
public static <T> T findByNameOrNull(String entityType, String fqn, Include include) {
EntityRepository<?> entityRepository = Entity.getEntityRepository(entityType);
@SuppressWarnings("unchecked")
T entity = (T) entityRepository.findByNameOrNull(fqn, include);
return entity;
}
public static <T> T getEntityByName(
String entityType, String fqn, String fields, Include include) {
return getEntityByName(entityType, fqn, fields, include, true);

View File

@ -48,7 +48,7 @@ import static org.openmetadata.service.Entity.FIELD_TAGS;
import static org.openmetadata.service.Entity.FIELD_VOTES;
import static org.openmetadata.service.Entity.TEAM;
import static org.openmetadata.service.Entity.USER;
import static org.openmetadata.service.Entity.getEntityByName;
import static org.openmetadata.service.Entity.findEntityByNameOrNull;
import static org.openmetadata.service.Entity.getEntityFields;
import static org.openmetadata.service.Entity.getEntityReferenceById;
import static org.openmetadata.service.exception.CatalogExceptionMessage.csvNotSupported;
@ -3660,10 +3660,16 @@ public abstract class EntityRepository<T extends EntityInterface> {
this.original = original;
this.updated = updated;
this.operation = operation;
this.updatingUser =
User updatingUser =
updated.getUpdatedBy().equalsIgnoreCase(ADMIN_USER_NAME)
? new User().withName(ADMIN_USER_NAME).withIsAdmin(true)
: getEntityByName(USER, updated.getUpdatedBy(), "", NON_DELETED);
: findEntityByNameOrNull(USER, updated.getUpdatedBy(), ALL);
if (updatingUser == null) {
// user not found, create a new user with name
// This is to handle the case where the user is not found in the system. maybe deleted
updatingUser = new User().withName(updated.getUpdatedBy()).withIsAdmin(false);
}
this.updatingUser = updatingUser;
this.changeSource = changeSource;
this.useOptimisticLocking = useOptimisticLocking;
}

View File

@ -2552,4 +2552,65 @@ public class UserResourceTest extends EntityResourceTest<User, CreateUser> {
// Verify user no longer exists in RDF after hard delete
RdfTestUtils.verifyEntityNotInRdf(user.getFullyQualifiedName());
}
@Test
void test_loginWithDeletedUpdatedByUser_200_ok(TestInfo test) throws HttpResponseException {
// Create an admin user to update another user
String username = "tempAdmin";
Map<String, String> TEMP_ADMIN_AUTH_HEADERS = authHeaders(username + "@open-metadata.org");
User adminUser =
createEntity(createRequest("tempAdmin").withIsAdmin(true), TEMP_ADMIN_AUTH_HEADERS);
// Create a target user that will be updated by the admin
User targetUser =
createEntity(
createRequest(test)
.withName("targetUser")
.withDisplayName("Target User")
.withEmail("targetuser@email.com")
.withIsBot(false)
.withCreatePasswordType(CreateUser.CreatePasswordType.ADMIN_CREATE)
.withPassword("Test@1234")
.withConfirmPassword("Test@1234"),
TEMP_ADMIN_AUTH_HEADERS);
assertEquals(adminUser.getName(), targetUser.getUpdatedBy());
// Delete the admin user who updated the target user
deleteEntity(adminUser.getId(), ADMIN_AUTH_HEADERS);
// Verify admin user is deleted
assertResponse(
() -> getEntity(adminUser.getId(), ADMIN_AUTH_HEADERS),
NOT_FOUND,
CatalogExceptionMessage.entityNotFound(Entity.USER, adminUser.getId()));
// Try to login with the target user - this should not throw an exception
// even though the updatedBy user (adminUser) has been deleted
LoginRequest loginRequest =
new LoginRequest()
.withEmail("targetuser@email.com")
.withPassword(encodePassword("Test@1234"));
// This login should succeed without throwing an exception
// The bug fix ensures that when updateUserLastLoginTime is called,
// it handles the case where the updatedBy user no longer exists
JwtResponse jwtResponse =
TestUtils.post(
getResource("users/login"),
loginRequest,
JwtResponse.class,
OK.getStatusCode(),
ADMIN_AUTH_HEADERS);
assertNotNull(jwtResponse);
assertNotNull(jwtResponse.getAccessToken());
// Verify the target user still has the deleted admin user name in updatedBy
User loggedInUser = getEntity(targetUser.getId(), ADMIN_AUTH_HEADERS);
assertEquals(adminUser.getName(), loggedInUser.getUpdatedBy());
// Clean up
deleteEntity(targetUser.getId(), ADMIN_AUTH_HEADERS);
}
}