Display proper error message if LDAP-linked user couldn't be deleted due to read-only mode

This commit is contained in:
mposolda 2014-08-26 19:10:48 +02:00
parent 892fa04130
commit b3b480c25f
5 changed files with 41 additions and 3 deletions

View file

@ -126,7 +126,10 @@ public class LDAPFederationProvider implements UserFederationProvider {
@Override
public boolean removeUser(RealmModel realm, UserModel user) {
if (editMode == EditMode.READ_ONLY || editMode == EditMode.UNSYNCED) return false;
if (editMode == EditMode.READ_ONLY || editMode == EditMode.UNSYNCED) {
logger.warnf("User '%s' can't be deleted in LDAP as editMode is '%s'", user.getUsername(), editMode.toString());
return false;
}
try {
return LDAPUtils.removeUser(partitionManager, user.getUsername());

View file

@ -253,6 +253,8 @@ module.controller('UserDetailCtrl', function($scope, realm, user, User, UserFede
}, function() {
$location.url("/realms/" + realm.realm + "/users");
Notifications.success("The user has been deleted.");
}, function() {
Notifications.error("User couldn't be deleted");
});
});
};

View file

@ -7,11 +7,16 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jboss.logging.Logger;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class UserFederationManager implements UserProvider {
private static final Logger logger = Logger.getLogger(UserFederationManager.class);
protected KeycloakSession session;
public UserFederationManager(KeycloakSession session) {
@ -83,6 +88,7 @@ public class UserFederationManager implements UserProvider {
RealmModel realmModel = tx.realms().getRealm(realm.getId());
UserModel deletedUser = tx.userStorage().getUserById(user.getId(), realmModel);
tx.userStorage().removeUser(realmModel, deletedUser);
logger.debugf("Removed invalid user '%s'", user.getUsername());
tx.getTransaction().commit();
} finally {
tx.close();

View file

@ -305,7 +305,7 @@ public class UsersResource {
@Path("{username}")
@DELETE
@NoCache
public void deleteUser(final @PathParam("username") String username) {
public Response deleteUser(final @PathParam("username") String username) {
auth.requireManage();
UserModel user = session.users().getUserByUsername(username, realm);
@ -313,7 +313,12 @@ public class UsersResource {
throw new NotFoundException("User not found");
}
new UserManager(session).removeUser(realm, user);
boolean removed = new UserManager(session).removeUser(realm, user);
if (removed) {
return Response.noContent().build();
} else {
return Flows.errors().error("User couldn't be deleted", Response.Status.BAD_REQUEST);
}
}
/**

View file

@ -236,6 +236,23 @@ public class FederationProvidersIntegrationTest {
}
}
@Test
public void testRemoveFederatedUser() {
KeycloakSession session = keycloakRule.startSession();
try {
RealmModel appRealm = session.realms().getRealmByName("test");
UserModel user = session.users().getUserByUsername("registerUserSuccess2", appRealm);
Assert.assertNotNull(user);
Assert.assertNotNull(user.getFederationLink());
Assert.assertEquals(user.getFederationLink(), ldapModel.getId());
Assert.assertTrue(session.users().removeUser(appRealm, user));
Assert.assertNull(session.users().getUserByUsername("registerUserSuccess2", appRealm));
} finally {
keycloakRule.stopSession(session, true);
}
}
@Test
public void testReadonly() {
KeycloakSession session = keycloakRule.startSession();
@ -275,6 +292,8 @@ public class FederationProvidersIntegrationTest {
} catch (ModelReadOnlyException e) {
}
Assert.assertFalse(session.users().removeUser(appRealm, user));
} finally {
keycloakRule.stopSession(session, false);
}
@ -311,6 +330,9 @@ public class FederationProvidersIntegrationTest {
// LDAP password is still unchanged
Assert.assertTrue(LDAPUtils.validatePassword(getPartitionManager(session, model), "johnkeycloak", "new-password"));
// ATM it's not permitted to delete user in unsynced mode. Should be user deleted just locally instead?
Assert.assertFalse(session.users().removeUser(appRealm, user));
} finally {
keycloakRule.stopSession(session, false);
}