Merge pull request #3600 from patriot1burke/master

KEYCLOAK-3986
This commit is contained in:
Bill Burke 2016-12-03 10:14:59 -05:00 committed by GitHub
commit e3f5df3894
4 changed files with 55 additions and 5 deletions

View file

@ -174,8 +174,9 @@ public class LDAPStorageProvider implements UserStorageProvider,
@Override
public UserModel addUser(RealmModel realm, String username) {
if (editMode == UserStorageProvider.EditMode.READ_ONLY || editMode == UserStorageProvider.EditMode.UNSYNCED) throw new IllegalStateException("Registration is not supported by this ldap server");
if (!synchronizeRegistrations()) throw new IllegalStateException("Registration is not supported by this ldap server");
if (!synchronizeRegistrations()) {
return null;
}
UserModel user = session.userLocalStorage().addUser(realm, username);
user.setFederationLink(model.getId());
LDAPObject ldapUser = LDAPUtils.addUserToLDAP(this, realm, user);

View file

@ -29,8 +29,35 @@ import org.keycloak.models.UserModel;
*/
public interface UserRegistrationProvider {
/**
* All storage providers that implement this interface will be looped through.
* If this method returns null, then the next storage provider's addUser() method will be called.
* If no storage providers handle the add, then the user will be created in local storage.
*
* Returning null is useful when you want optional support for adding users. For example,
* our LDAP provider can enable and disable the ability to add users.
*
* @param realm
* @param username
* @return
*/
UserModel addUser(RealmModel realm, String username);
/**
* Called if user originated from this provider.
*
*
* If a local user is linked to this provider, this method will be called before
* local storage's removeUser() method is invoked.
* If you are using an import strategy, and this is a local user linked to this provider,
* this method will be called before local storage's removeUser() method is invoked. Also,
* you DO NOT need to remove the imported user. The runtime will handle this for you.
*
* @param realm
* @param user
* @return
*/
boolean removeUser(RealmModel realm, UserModel user);

View file

@ -116,10 +116,11 @@ public class UserStorageManager implements UserProvider, OnUserCache {
@Override
public UserModel addUser(RealmModel realm, String username) {
UserRegistrationProvider registry = getFirstStorageProvider(session, realm, UserRegistrationProvider.class);
if (registry != null) {
return registry.addUser(realm, username);
for (UserRegistrationProvider provider : getStorageProviders(session, realm, UserRegistrationProvider.class)) {
UserModel user = provider.addUser(realm, username);
if (user != null) return user;
}
return localStorage().addUser(realm, username.toLowerCase());
}

View file

@ -149,6 +149,27 @@ public class LDAPProvidersIntegrationTest {
//
// }
/**
* KEYCLOAK-3986
*
*/
@Test
public void testSyncRegistrationOff() {
KeycloakSession session = keycloakRule.startSession();
try {
RealmManager manager = new RealmManager(session);
RealmModel appRealm = manager.getRealm("test");
UserStorageProviderModel newModel = new UserStorageProviderModel(ldapModel);
newModel.getConfig().putSingle(LDAPConstants.SYNC_REGISTRATIONS, "false");
appRealm.updateComponent(newModel);
UserModel newUser1 = session.users().addUser(appRealm, "newUser1");
Assert.assertNull(newUser1.getFederationLink());
} finally {
keycloakRule.stopSession(session, false);
}
}
@Test
public void caseInSensitiveImport() {