Merge pull request #318 from mposolda/ldap
Basic support for registration of new users in AuthenticationProvider (like LDAP). Other improvements in auth SPI
This commit is contained in:
commit
a0cd2bf5a7
14 changed files with 192 additions and 33 deletions
|
@ -31,5 +31,5 @@ public interface Account {
|
||||||
|
|
||||||
Account setEvents(List<Event> events);
|
Account setEvents(List<Event> events);
|
||||||
|
|
||||||
Account setFeatures(boolean social, boolean audit);
|
Account setFeatures(boolean social, boolean audit, boolean passwordUpdateSupported);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ public class FreeMarkerAccount implements Account {
|
||||||
private List<Event> events;
|
private List<Event> events;
|
||||||
private boolean social;
|
private boolean social;
|
||||||
private boolean audit;
|
private boolean audit;
|
||||||
|
private boolean passwordUpdateSupported;
|
||||||
|
|
||||||
public static enum MessageType {SUCCESS, WARNING, ERROR}
|
public static enum MessageType {SUCCESS, WARNING, ERROR}
|
||||||
|
|
||||||
|
@ -95,7 +96,7 @@ public class FreeMarkerAccount implements Account {
|
||||||
|
|
||||||
attributes.put("url", new UrlBean(realm, theme, baseUri));
|
attributes.put("url", new UrlBean(realm, theme, baseUri));
|
||||||
|
|
||||||
attributes.put("features", new FeaturesBean(social, audit));
|
attributes.put("features", new FeaturesBean(social, audit, passwordUpdateSupported));
|
||||||
|
|
||||||
switch (page) {
|
switch (page) {
|
||||||
case ACCOUNT:
|
case ACCOUNT:
|
||||||
|
@ -172,9 +173,10 @@ public class FreeMarkerAccount implements Account {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Account setFeatures(boolean social, boolean audit) {
|
public Account setFeatures(boolean social, boolean audit, boolean passwordUpdateSupported) {
|
||||||
this.social = social;
|
this.social = social;
|
||||||
this.audit = audit;
|
this.audit = audit;
|
||||||
|
this.passwordUpdateSupported = passwordUpdateSupported;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,12 @@ public class FeaturesBean {
|
||||||
|
|
||||||
private final boolean social;
|
private final boolean social;
|
||||||
private final boolean log;
|
private final boolean log;
|
||||||
|
private final boolean passwordUpdateSupported;
|
||||||
|
|
||||||
public FeaturesBean(boolean social, boolean log) {
|
public FeaturesBean(boolean social, boolean log, boolean passwordUpdateSupported) {
|
||||||
this.social = social;
|
this.social = social;
|
||||||
this.log = log;
|
this.log = log;
|
||||||
|
this.passwordUpdateSupported = passwordUpdateSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSocial() {
|
public boolean isSocial() {
|
||||||
|
@ -21,4 +23,7 @@ public class FeaturesBean {
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPasswordUpdateSupported() {
|
||||||
|
return passwordUpdateSupported;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<div class="bs-sidebar col-sm-3 ng-scope">
|
<div class="bs-sidebar col-sm-3 ng-scope">
|
||||||
<ul>
|
<ul>
|
||||||
<li class="<#if active=='account'>active</#if>"><a href="${url.accountUrl}">Account</a></li>
|
<li class="<#if active=='account'>active</#if>"><a href="${url.accountUrl}">Account</a></li>
|
||||||
<li class="<#if active=='password'>active</#if>"><a href="${url.passwordUrl}">Password</a></li>
|
<#if features.passwordUpdateSupported><li class="<#if active=='password'>active</#if>"><a href="${url.passwordUrl}">Password</a></li></#if>
|
||||||
<li class="<#if active=='totp'>active</#if>"><a href="${url.totpUrl}">Authenticator</a></li>
|
<li class="<#if active=='totp'>active</#if>"><a href="${url.totpUrl}">Authenticator</a></li>
|
||||||
<#if features.social><li class="<#if active=='social'>active</#if>"><a href="${url.socialUrl}">Social</a></li></#if>
|
<#if features.social><li class="<#if active=='social'>active</#if>"><a href="${url.socialUrl}">Social</a></li></#if>
|
||||||
<#if features.log><li class="<#if active=='log'>active</#if>"><a href="${url.logUrl}">Log</a></li></#if>
|
<#if features.log><li class="<#if active=='log'>active</#if>"><a href="${url.logUrl}">Log</a></li></#if>
|
||||||
|
|
|
@ -231,6 +231,7 @@ public class AuthenticationManager {
|
||||||
user.setLastName(authUser.getLastName());
|
user.setLastName(authUser.getLastName());
|
||||||
user.setEmail(authUser.getEmail());
|
user.setEmail(authUser.getEmail());
|
||||||
realm.setAuthenticationLink(user, new AuthenticationLinkModel(authUser.getProviderName(), authUser.getId()));
|
realm.setAuthenticationLink(user, new AuthenticationLinkModel(authUser.getProviderName(), authUser.getId()));
|
||||||
|
logger.info("User " + authUser.getUsername() + " created and linked with provider " + authUser.getProviderName());
|
||||||
} else {
|
} else {
|
||||||
logger.warn("User " + username + " not found");
|
logger.warn("User " + username + " not found");
|
||||||
return AuthenticationStatus.INVALID_USER;
|
return AuthenticationStatus.INVALID_USER;
|
||||||
|
|
|
@ -35,6 +35,8 @@ import org.keycloak.audit.Events;
|
||||||
import org.keycloak.jaxrs.JaxrsOAuthClient;
|
import org.keycloak.jaxrs.JaxrsOAuthClient;
|
||||||
import org.keycloak.models.AccountRoles;
|
import org.keycloak.models.AccountRoles;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
|
import org.keycloak.models.AuthenticationLinkModel;
|
||||||
|
import org.keycloak.models.AuthenticationProviderModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
@ -143,12 +145,21 @@ public class AccountService {
|
||||||
public void init() {
|
public void init() {
|
||||||
auditProvider = providers.getProvider(AuditProvider.class);
|
auditProvider = providers.getProvider(AuditProvider.class);
|
||||||
|
|
||||||
account = AccountLoader.load().createAccount(uriInfo).setRealm(realm).setFeatures(realm.isSocial(), auditProvider != null);
|
account = AccountLoader.load().createAccount(uriInfo).setRealm(realm);
|
||||||
|
|
||||||
|
boolean passwordUpdateSupported = false;
|
||||||
auth = authManager.authenticate(realm, headers);
|
auth = authManager.authenticate(realm, headers);
|
||||||
if (auth != null) {
|
if (auth != null) {
|
||||||
account.setUser(auth.getUser());
|
account.setUser(auth.getUser());
|
||||||
|
|
||||||
|
AuthenticationLinkModel authLinkModel = realm.getAuthenticationLink(auth.getUser());
|
||||||
|
if (authLinkModel != null) {
|
||||||
|
AuthenticationProviderModel authProviderModel = AuthenticationProviderManager.getConfiguredProviderModel(realm, authLinkModel.getAuthProvider());
|
||||||
|
passwordUpdateSupported = authProviderModel.isPasswordUpdateSupported();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
account.setFeatures(realm.isSocial(), auditProvider != null, passwordUpdateSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UriBuilder accountServiceBaseUrl(UriInfo uriInfo) {
|
public static UriBuilder accountServiceBaseUrl(UriInfo uriInfo) {
|
||||||
|
|
|
@ -383,13 +383,15 @@ public class TokenService {
|
||||||
return Flows.forms(realm, request, uriInfo).setError(error).setFormData(formData).createRegistration();
|
return Flows.forms(realm, request, uriInfo).setError(error).setFormData(formData).createRegistration();
|
||||||
}
|
}
|
||||||
|
|
||||||
UserModel user = realm.getUser(username);
|
AuthenticationProviderManager authenticationProviderManager = AuthenticationProviderManager.getManager(realm);
|
||||||
if (user != null) {
|
|
||||||
|
// Validate that user with this username doesn't exist in realm or any authentication provider
|
||||||
|
if (realm.getUser(username) != null || authenticationProviderManager.getUser(username) != null) {
|
||||||
audit.error(Errors.USERNAME_IN_USE);
|
audit.error(Errors.USERNAME_IN_USE);
|
||||||
return Flows.forms(realm, request, uriInfo).setError(Messages.USERNAME_EXISTS).setFormData(formData).createRegistration();
|
return Flows.forms(realm, request, uriInfo).setError(Messages.USERNAME_EXISTS).setFormData(formData).createRegistration();
|
||||||
}
|
}
|
||||||
|
|
||||||
user = realm.addUser(username);
|
UserModel user = realm.addUser(username);
|
||||||
user.setEnabled(true);
|
user.setEnabled(true);
|
||||||
user.setFirstName(formData.getFirst("firstName"));
|
user.setFirstName(formData.getFirst("firstName"));
|
||||||
user.setLastName(formData.getFirst("lastName"));
|
user.setLastName(formData.getFirst("lastName"));
|
||||||
|
|
|
@ -29,6 +29,14 @@ public abstract class AbstractModelAuthenticationProvider implements Authenticat
|
||||||
return user == null ? null : createAuthenticatedUserInstance(user);
|
return user == null ? null : createAuthenticatedUserInstance(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String registerUser(RealmModel currentRealm, Map<String, String> config, String username) throws AuthenticationProviderException {
|
||||||
|
RealmModel realm = getRealm(currentRealm, config);
|
||||||
|
UserModel user = currentRealm.addUser(username);
|
||||||
|
user.setEnabled(true);
|
||||||
|
return user.getId();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthProviderStatus validatePassword(RealmModel currentRealm, Map<String, String> config, String username, String password) throws AuthenticationProviderException {
|
public AuthProviderStatus validatePassword(RealmModel currentRealm, Map<String, String> config, String username, String password) throws AuthenticationProviderException {
|
||||||
RealmModel realm = getRealm(currentRealm, config);
|
RealmModel realm = getRealm(currentRealm, config);
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.keycloak.spi.authentication.AuthenticationProvider;
|
||||||
import org.keycloak.spi.authentication.AuthenticationProviderException;
|
import org.keycloak.spi.authentication.AuthenticationProviderException;
|
||||||
import org.keycloak.spi.picketlink.PartitionManagerProvider;
|
import org.keycloak.spi.picketlink.PartitionManagerProvider;
|
||||||
import org.keycloak.util.ProviderLoader;
|
import org.keycloak.util.ProviderLoader;
|
||||||
|
import org.picketlink.idm.IdentityManagementException;
|
||||||
import org.picketlink.idm.IdentityManager;
|
import org.picketlink.idm.IdentityManager;
|
||||||
import org.picketlink.idm.PartitionManager;
|
import org.picketlink.idm.PartitionManager;
|
||||||
import org.picketlink.idm.credential.Credentials;
|
import org.picketlink.idm.credential.Credentials;
|
||||||
|
@ -44,25 +45,47 @@ public class PicketlinkAuthenticationProvider implements AuthenticationProvider
|
||||||
@Override
|
@Override
|
||||||
public AuthUser getUser(RealmModel realm, Map<String, String> configuration, String username) throws AuthenticationProviderException {
|
public AuthUser getUser(RealmModel realm, Map<String, String> configuration, String username) throws AuthenticationProviderException {
|
||||||
IdentityManager identityManager = getIdentityManager(realm);
|
IdentityManager identityManager = getIdentityManager(realm);
|
||||||
User picketlinkUser = BasicModel.getUser(identityManager, username);
|
|
||||||
return picketlinkUser == null ? null : new AuthUser(picketlinkUser.getId(), picketlinkUser.getLoginName(), getName())
|
try {
|
||||||
.setName(picketlinkUser.getFirstName(), picketlinkUser.getLastName())
|
User picketlinkUser = BasicModel.getUser(identityManager, username);
|
||||||
.setEmail(picketlinkUser.getEmail())
|
return picketlinkUser == null ? null : new AuthUser(picketlinkUser.getId(), picketlinkUser.getLoginName(), getName())
|
||||||
.setProviderName(getName());
|
.setName(picketlinkUser.getFirstName(), picketlinkUser.getLastName())
|
||||||
|
.setEmail(picketlinkUser.getEmail())
|
||||||
|
.setProviderName(getName());
|
||||||
|
} catch (IdentityManagementException ie) {
|
||||||
|
throw convertIDMException(ie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String registerUser(RealmModel realm, Map<String, String> configuration, String username) throws AuthenticationProviderException {
|
||||||
|
IdentityManager identityManager = getIdentityManager(realm);
|
||||||
|
|
||||||
|
try {
|
||||||
|
User picketlinkUser = new User(username);
|
||||||
|
identityManager.add(picketlinkUser);
|
||||||
|
return picketlinkUser.getId();
|
||||||
|
} catch (IdentityManagementException ie) {
|
||||||
|
throw convertIDMException(ie);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthProviderStatus validatePassword(RealmModel realm, Map<String, String> configuration, String username, String password) throws AuthenticationProviderException {
|
public AuthProviderStatus validatePassword(RealmModel realm, Map<String, String> configuration, String username, String password) throws AuthenticationProviderException {
|
||||||
IdentityManager identityManager = getIdentityManager(realm);
|
IdentityManager identityManager = getIdentityManager(realm);
|
||||||
|
|
||||||
UsernamePasswordCredentials credential = new UsernamePasswordCredentials();
|
try {
|
||||||
credential.setUsername(username);
|
UsernamePasswordCredentials credential = new UsernamePasswordCredentials();
|
||||||
credential.setPassword(new Password(password.toCharArray()));
|
credential.setUsername(username);
|
||||||
identityManager.validateCredentials(credential);
|
credential.setPassword(new Password(password.toCharArray()));
|
||||||
if (credential.getStatus() == Credentials.Status.VALID) {
|
identityManager.validateCredentials(credential);
|
||||||
return AuthProviderStatus.SUCCESS;
|
if (credential.getStatus() == Credentials.Status.VALID) {
|
||||||
} else {
|
return AuthProviderStatus.SUCCESS;
|
||||||
return AuthProviderStatus.INVALID_CREDENTIALS;
|
} else {
|
||||||
|
return AuthProviderStatus.INVALID_CREDENTIALS;
|
||||||
|
}
|
||||||
|
} catch (IdentityManagementException ie) {
|
||||||
|
throw convertIDMException(ie);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,14 +93,18 @@ public class PicketlinkAuthenticationProvider implements AuthenticationProvider
|
||||||
public boolean updateCredential(RealmModel realm, Map<String, String> configuration, String username, String password) throws AuthenticationProviderException {
|
public boolean updateCredential(RealmModel realm, Map<String, String> configuration, String username, String password) throws AuthenticationProviderException {
|
||||||
IdentityManager identityManager = getIdentityManager(realm);
|
IdentityManager identityManager = getIdentityManager(realm);
|
||||||
|
|
||||||
User picketlinkUser = BasicModel.getUser(identityManager, username);
|
try {
|
||||||
if (picketlinkUser == null) {
|
User picketlinkUser = BasicModel.getUser(identityManager, username);
|
||||||
logger.debugf("User '%s' doesn't exists. Skip password update", username);
|
if (picketlinkUser == null) {
|
||||||
return false;
|
logger.debugf("User '%s' doesn't exists. Skip password update", username);
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
identityManager.updateCredential(picketlinkUser, new Password(password.toCharArray()));
|
identityManager.updateCredential(picketlinkUser, new Password(password.toCharArray()));
|
||||||
return true;
|
return true;
|
||||||
|
} catch (IdentityManagementException ie) {
|
||||||
|
throw convertIDMException(ie);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IdentityManager getIdentityManager(RealmModel realm) throws AuthenticationProviderException {
|
public IdentityManager getIdentityManager(RealmModel realm) throws AuthenticationProviderException {
|
||||||
|
@ -103,4 +130,14 @@ public class PicketlinkAuthenticationProvider implements AuthenticationProvider
|
||||||
}
|
}
|
||||||
return identityManager;
|
return identityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AuthenticationProviderException convertIDMException(IdentityManagementException ie) {
|
||||||
|
Throwable realCause = ie;
|
||||||
|
while (realCause.getCause() != null) {
|
||||||
|
realCause = realCause.getCause();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the message from the realCause
|
||||||
|
return new AuthenticationProviderException(realCause.getMessage(), ie);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,17 @@ public interface AuthenticationProvider {
|
||||||
*/
|
*/
|
||||||
AuthUser getUser(RealmModel realm, Map<String, String> configuration, String username) throws AuthenticationProviderException;
|
AuthUser getUser(RealmModel realm, Map<String, String> configuration, String username) throws AuthenticationProviderException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to register user with this authentication provider
|
||||||
|
*
|
||||||
|
* @param realm
|
||||||
|
* @param configuration
|
||||||
|
* @param username
|
||||||
|
* @return ID of newly created user (For example ID from LDAP)
|
||||||
|
* @throws AuthenticationProviderException if user creation couldn't happen
|
||||||
|
*/
|
||||||
|
String registerUser(RealmModel realm, Map<String, String> configuration, String username) throws AuthenticationProviderException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard Authentication flow
|
* Standard Authentication flow
|
||||||
*
|
*
|
||||||
|
|
|
@ -73,7 +73,11 @@ public class AuthenticationProviderManager {
|
||||||
public AuthProviderStatus validatePassword(UserModel user, String password) {
|
public AuthProviderStatus validatePassword(UserModel user, String password) {
|
||||||
AuthenticationLinkModel authLink = realm.getAuthenticationLink(user);
|
AuthenticationLinkModel authLink = realm.getAuthenticationLink(user);
|
||||||
if (authLink == null) {
|
if (authLink == null) {
|
||||||
authLink = new AuthenticationLinkModel(AuthenticationProviderModel.DEFAULT_PROVIDER.getProviderName(), user.getId());
|
// User not yet linked with any authenticationProvider. Find provider with biggest priority where he is and link
|
||||||
|
AuthUser authUser = getUser(user.getLoginName());
|
||||||
|
authLink = new AuthenticationLinkModel(authUser.getProviderName(), authUser.getId());
|
||||||
|
realm.setAuthenticationLink(user, authLink);
|
||||||
|
logger.infof("User '%s' linked with provider '%s'", authUser.getUsername(), authUser.getProviderName());
|
||||||
}
|
}
|
||||||
|
|
||||||
String providerName = authLink.getAuthProvider();
|
String providerName = authLink.getAuthProvider();
|
||||||
|
@ -99,7 +103,38 @@ public class AuthenticationProviderManager {
|
||||||
public boolean updatePassword(UserModel user, String password) throws AuthenticationProviderException {
|
public boolean updatePassword(UserModel user, String password) throws AuthenticationProviderException {
|
||||||
AuthenticationLinkModel authLink = realm.getAuthenticationLink(user);
|
AuthenticationLinkModel authLink = realm.getAuthenticationLink(user);
|
||||||
if (authLink == null) {
|
if (authLink == null) {
|
||||||
authLink = new AuthenticationLinkModel(AuthenticationProviderModel.DEFAULT_PROVIDER.getProviderName(), user.getId());
|
// Find provider with biggest priority where password update is supported. Then register user here and link him
|
||||||
|
List<AuthenticationProviderModel> configuredProviders = getConfiguredProviderModels(realm);
|
||||||
|
for (AuthenticationProviderModel providerModel : configuredProviders) {
|
||||||
|
if (providerModel.isPasswordUpdateSupported()) {
|
||||||
|
AuthenticationProvider delegate = getProvider(providerModel.getProviderName());
|
||||||
|
if (delegate != null) {
|
||||||
|
AuthUser authUser = delegate.getUser(realm, providerModel.getConfig(), user.getLoginName());
|
||||||
|
if (authUser != null) {
|
||||||
|
// Linking existing user supported just for "model" provider. In other cases throw exception
|
||||||
|
if (providerModel.getProviderName().equals(AuthenticationProviderModel.DEFAULT_PROVIDER.getProviderName())) {
|
||||||
|
authLink = new AuthenticationLinkModel(providerModel.getProviderName(), authUser.getId());
|
||||||
|
realm.setAuthenticationLink(user, authLink);
|
||||||
|
logger.infof("User '%s' linked with provider '%s'", authUser.getUsername(), authUser.getProviderName());
|
||||||
|
} else {
|
||||||
|
throw new AuthenticationProviderException("User " + authUser.getUsername() + " exists in provider "
|
||||||
|
+ authUser.getProviderName() + " but is not linked with model user");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String userIdInProvider = delegate.registerUser(realm, providerModel.getConfig(), user.getLoginName());
|
||||||
|
authLink = new AuthenticationLinkModel(providerModel.getProviderName(), userIdInProvider);
|
||||||
|
realm.setAuthenticationLink(user, authLink);
|
||||||
|
logger.infof("User '%s' registered in provider '%s' and linked", user.getLoginName(), providerModel.getProviderName());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authLink == null) {
|
||||||
|
logger.warnf("No providers found where password update is supported for user '%s'", user.getLoginName());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String providerName = authLink.getAuthProvider();
|
String providerName = authLink.getAuthProvider();
|
||||||
|
@ -147,7 +182,7 @@ public class AuthenticationProviderManager {
|
||||||
return delegate;
|
return delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AuthenticationProviderModel> getConfiguredProviderModels(RealmModel realm) {
|
private static List<AuthenticationProviderModel> getConfiguredProviderModels(RealmModel realm) {
|
||||||
List<AuthenticationProviderModel> configuredProviders = realm.getAuthenticationProviders();
|
List<AuthenticationProviderModel> configuredProviders = realm.getAuthenticationProviders();
|
||||||
|
|
||||||
// Use model based authentication of current realm by default
|
// Use model based authentication of current realm by default
|
||||||
|
@ -159,7 +194,7 @@ public class AuthenticationProviderManager {
|
||||||
return configuredProviders;
|
return configuredProviders;
|
||||||
}
|
}
|
||||||
|
|
||||||
private AuthenticationProviderModel getConfiguredProviderModel(RealmModel realm, String providerName) {
|
public static AuthenticationProviderModel getConfiguredProviderModel(RealmModel realm, String providerName) {
|
||||||
List<AuthenticationProviderModel> providers = getConfiguredProviderModels(realm);
|
List<AuthenticationProviderModel> providers = getConfiguredProviderModels(realm);
|
||||||
for (AuthenticationProviderModel provider : providers) {
|
for (AuthenticationProviderModel provider : providers) {
|
||||||
if (providerName.equals(provider.getProviderName())) {
|
if (providerName.equals(provider.getProviderName())) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.keycloak.testsuite.pages.AccountPasswordPage;
|
||||||
import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
|
import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
|
||||||
import org.keycloak.testsuite.pages.AppPage;
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
|
import org.keycloak.testsuite.pages.RegisterPage;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||||
import org.keycloak.testsuite.rule.LDAPRule;
|
import org.keycloak.testsuite.rule.LDAPRule;
|
||||||
import org.keycloak.testsuite.rule.WebResource;
|
import org.keycloak.testsuite.rule.WebResource;
|
||||||
|
@ -82,6 +83,9 @@ public class AuthProvidersIntegrationTest {
|
||||||
@WebResource
|
@WebResource
|
||||||
protected AppPage appPage;
|
protected AppPage appPage;
|
||||||
|
|
||||||
|
@WebResource
|
||||||
|
protected RegisterPage registerPage;
|
||||||
|
|
||||||
@WebResource
|
@WebResource
|
||||||
protected LoginPage loginPage;
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
|
@ -111,6 +115,9 @@ public class AuthProvidersIntegrationTest {
|
||||||
|
|
||||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
||||||
|
|
||||||
|
profilePage.open();
|
||||||
|
Assert.assertFalse(profilePage.isPasswordUpdateSupported());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -120,6 +127,9 @@ public class AuthProvidersIntegrationTest {
|
||||||
|
|
||||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
||||||
|
|
||||||
|
profilePage.open();
|
||||||
|
Assert.assertTrue(profilePage.isPasswordUpdateSupported());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -131,6 +141,7 @@ public class AuthProvidersIntegrationTest {
|
||||||
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
||||||
|
|
||||||
profilePage.open();
|
profilePage.open();
|
||||||
|
Assert.assertTrue(profilePage.isPasswordUpdateSupported());
|
||||||
Assert.assertEquals("John", profilePage.getFirstName());
|
Assert.assertEquals("John", profilePage.getFirstName());
|
||||||
Assert.assertEquals("Doe", profilePage.getLastName());
|
Assert.assertEquals("Doe", profilePage.getLastName());
|
||||||
Assert.assertEquals("john@email.org", profilePage.getEmail());
|
Assert.assertEquals("john@email.org", profilePage.getEmail());
|
||||||
|
@ -191,4 +202,26 @@ public class AuthProvidersIntegrationTest {
|
||||||
loginPage.login("john", "new-password");
|
loginPage.login("john", "new-password");
|
||||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void registerExistingLdapUser() {
|
||||||
|
loginPage.open();
|
||||||
|
loginPage.clickRegister();
|
||||||
|
registerPage.assertCurrent();
|
||||||
|
|
||||||
|
registerPage.register("firstName", "lastName", "email", "existing", "password", "password");
|
||||||
|
|
||||||
|
registerPage.assertCurrent();
|
||||||
|
Assert.assertEquals("Username already exists", registerPage.getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void registerUserLdapSuccess() {
|
||||||
|
loginPage.open();
|
||||||
|
loginPage.clickRegister();
|
||||||
|
registerPage.assertCurrent();
|
||||||
|
|
||||||
|
registerPage.register("firstName", "lastName", "email", "registerUserSuccess", "password", "password");
|
||||||
|
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,4 +96,8 @@ public class AccountUpdateProfilePage extends AbstractAccountPage {
|
||||||
public String getError() {
|
public String getError() {
|
||||||
return errorMessage.getText();
|
return errorMessage.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPasswordUpdateSupported() {
|
||||||
|
return driver.getPageSource().contains(PATH + "/password");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,3 +28,13 @@ uid: john
|
||||||
cn: John
|
cn: John
|
||||||
sn: Doe
|
sn: Doe
|
||||||
mail: john@email.org
|
mail: john@email.org
|
||||||
|
|
||||||
|
dn: uid=existing,ou=People,dc=keycloak,dc=org
|
||||||
|
objectclass: top
|
||||||
|
objectclass: uidObject
|
||||||
|
objectclass: person
|
||||||
|
objectclass: inetOrgPerson
|
||||||
|
uid: existing
|
||||||
|
cn: Existing
|
||||||
|
sn: Foo
|
||||||
|
mail: existing@email.org
|
||||||
|
|
Loading…
Reference in a new issue