KEYCLOAK-15524 Cleanup user related interfaces
This commit is contained in:
parent
dae4a3eaf2
commit
ba8e2fef6b
145 changed files with 1625 additions and 1381 deletions
|
@ -349,7 +349,7 @@ public class UMAPolicyProviderFactory implements PolicyProviderFactory<UmaPermis
|
||||||
UserPolicyRepresentation rep = UserPolicyRepresentation.class.cast(associatedRep);
|
UserPolicyRepresentation rep = UserPolicyRepresentation.class.cast(associatedRep);
|
||||||
|
|
||||||
for (String user : rep.getUsers()) {
|
for (String user : rep.getUsers()) {
|
||||||
representation.addUser(authorization.getKeycloakSession().users().getUserById(user, realm).getUsername());
|
representation.addUser(authorization.getKeycloakSession().users().getUserById(realm, user).getUsername());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory<UserPoli
|
||||||
UserProvider userProvider = authorizationProvider.getKeycloakSession().users();
|
UserProvider userProvider = authorizationProvider.getKeycloakSession().users();
|
||||||
RealmModel realm = authorizationProvider.getRealm();
|
RealmModel realm = authorizationProvider.getRealm();
|
||||||
|
|
||||||
config.put("users", JsonSerialization.writeValueAsString(userRep.getUsers().stream().map(id -> userProvider.getUserById(id, realm).getUsername()).collect(Collectors.toList())));
|
config.put("users", JsonSerialization.writeValueAsString(userRep.getUsers().stream().map(id -> userProvider.getUserById(realm, id).getUsername()).collect(Collectors.toList())));
|
||||||
} catch (IOException cause) {
|
} catch (IOException cause) {
|
||||||
throw new RuntimeException("Failed to export user policy [" + policy.getName() + "]", cause);
|
throw new RuntimeException("Failed to export user policy [" + policy.getName() + "]", cause);
|
||||||
}
|
}
|
||||||
|
@ -142,12 +142,12 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory<UserPoli
|
||||||
UserModel user = null;
|
UserModel user = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
user = userProvider.getUserByUsername(userId, realm);
|
user = userProvider.getUserByUsername(realm, userId);
|
||||||
} catch (Exception ignore) {
|
} catch (Exception ignore) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
user = userProvider.getUserById(userId, realm);
|
user = userProvider.getUserById(realm, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
|
|
@ -48,7 +48,7 @@ import java.util.stream.Stream;
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
public class KerberosFederationProvider implements UserStorageProvider,
|
public class KerberosFederationProvider implements UserStorageProvider,
|
||||||
UserLookupProvider,
|
UserLookupProvider.Streams,
|
||||||
CredentialInputValidator,
|
CredentialInputValidator,
|
||||||
CredentialInputUpdater.Streams,
|
CredentialInputUpdater.Streams,
|
||||||
CredentialAuthentication,
|
CredentialAuthentication,
|
||||||
|
@ -83,7 +83,7 @@ public class KerberosFederationProvider implements UserStorageProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
public UserModel getUserByUsername(RealmModel realm, String username) {
|
||||||
KerberosUsernamePasswordAuthenticator authenticator = factory.createKerberosUsernamePasswordAuthenticator(kerberosConfig);
|
KerberosUsernamePasswordAuthenticator authenticator = factory.createKerberosUsernamePasswordAuthenticator(kerberosConfig);
|
||||||
if (authenticator.isUserAvailable(username)) {
|
if (authenticator.isUserAvailable(username)) {
|
||||||
// Case when method was called with username including kerberos realm like john@REALM.ORG . Authenticator already checked that kerberos realm was correct
|
// Case when method was called with username including kerberos realm like john@REALM.ORG . Authenticator already checked that kerberos realm was correct
|
||||||
|
@ -98,12 +98,12 @@ public class KerberosFederationProvider implements UserStorageProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
public UserModel getUserByEmail(RealmModel realm, String email) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
public UserModel getUserById(RealmModel realm, String id) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,9 +234,9 @@ public class KerberosFederationProvider implements UserStorageProvider,
|
||||||
* @return user if found or successfully created. Null if user with same username already exists, but is not linked to this provider
|
* @return user if found or successfully created. Null if user with same username already exists, but is not linked to this provider
|
||||||
*/
|
*/
|
||||||
protected UserModel findOrCreateAuthenticatedUser(RealmModel realm, String username) {
|
protected UserModel findOrCreateAuthenticatedUser(RealmModel realm, String username) {
|
||||||
UserModel user = session.userLocalStorage().getUserByUsername(username, realm);
|
UserModel user = session.userLocalStorage().getUserByUsername(realm, username);
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
user = session.users().getUserById(user.getId(), realm); // make sure we get a cached instance
|
user = session.users().getUserById(realm, user.getId()); // make sure we get a cached instance
|
||||||
logger.debug("Kerberos authenticated user " + username + " found in Keycloak storage");
|
logger.debug("Kerberos authenticated user " + username + " found in Keycloak storage");
|
||||||
|
|
||||||
if (!model.getId().equals(user.getFederationLink())) {
|
if (!model.getId().equals(user.getFederationLink())) {
|
||||||
|
|
|
@ -79,6 +79,8 @@ import org.keycloak.storage.user.UserLookupProvider;
|
||||||
import org.keycloak.storage.user.UserQueryProvider;
|
import org.keycloak.storage.user.UserQueryProvider;
|
||||||
import org.keycloak.storage.user.UserRegistrationProvider;
|
import org.keycloak.storage.user.UserRegistrationProvider;
|
||||||
|
|
||||||
|
import static org.keycloak.utils.StreamsUtil.paginatedStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -88,11 +90,12 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
CredentialInputValidator,
|
CredentialInputValidator,
|
||||||
CredentialInputUpdater.Streams,
|
CredentialInputUpdater.Streams,
|
||||||
CredentialAuthentication,
|
CredentialAuthentication,
|
||||||
UserLookupProvider,
|
UserLookupProvider.Streams,
|
||||||
UserRegistrationProvider,
|
UserRegistrationProvider,
|
||||||
UserQueryProvider.Streams,
|
UserQueryProvider.Streams,
|
||||||
ImportedUserValidation {
|
ImportedUserValidation {
|
||||||
private static final Logger logger = Logger.getLogger(LDAPStorageProvider.class);
|
private static final Logger logger = Logger.getLogger(LDAPStorageProvider.class);
|
||||||
|
private static final int DEFAULT_MAX_RESULTS = Integer.MAX_VALUE >> 1;
|
||||||
|
|
||||||
protected LDAPStorageProviderFactory factory;
|
protected LDAPStorageProviderFactory factory;
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
|
@ -176,7 +179,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
|
|
||||||
// We need to avoid having CachedUserModel as cache is upper-layer then LDAP. Hence having CachedUserModel here may cause StackOverflowError
|
// We need to avoid having CachedUserModel as cache is upper-layer then LDAP. Hence having CachedUserModel here may cause StackOverflowError
|
||||||
if (local instanceof CachedUserModel) {
|
if (local instanceof CachedUserModel) {
|
||||||
local = session.userStorageManager().getUserById(local.getId(), realm);
|
local = session.userStorageManager().getUserById(realm, local.getId());
|
||||||
|
|
||||||
existing = userManager.getManagedProxiedUser(local.getId());
|
existing = userManager.getManagedProxiedUser(local.getId());
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
|
@ -245,7 +248,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
|
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
|
||||||
try (LDAPQuery ldapQuery = LDAPUtils.createQueryForUserSearch(this, realm)) {
|
try (LDAPQuery ldapQuery = LDAPUtils.createQueryForUserSearch(this, realm)) {
|
||||||
LDAPQueryConditionsBuilder conditionsBuilder = new LDAPQueryConditionsBuilder();
|
LDAPQueryConditionsBuilder conditionsBuilder = new LDAPQueryConditionsBuilder();
|
||||||
|
|
||||||
|
@ -256,7 +259,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
|
|
||||||
return ldapObjects.stream().map(ldapUser -> {
|
return ldapObjects.stream().map(ldapUser -> {
|
||||||
String ldapUsername = LDAPUtils.getUsername(ldapUser, this.ldapIdentityStore.getConfig());
|
String ldapUsername = LDAPUtils.getUsername(ldapUser, this.ldapIdentityStore.getConfig());
|
||||||
UserModel localUser = session.userLocalStorage().getUserByUsername(ldapUsername, realm);
|
UserModel localUser = session.userLocalStorage().getUserByUsername(realm, ldapUsername);
|
||||||
if (localUser == null) {
|
if (localUser == null) {
|
||||||
return importUserFromLDAP(session, realm, ldapUser);
|
return importUserFromLDAP(session, realm, ldapUser);
|
||||||
} else {
|
} else {
|
||||||
|
@ -323,12 +326,12 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
public UserModel getUserById(RealmModel realm, String id) {
|
||||||
UserModel alreadyLoadedInSession = userManager.getManagedProxiedUser(id);
|
UserModel alreadyLoadedInSession = userManager.getManagedProxiedUser(id);
|
||||||
if (alreadyLoadedInSession != null) return alreadyLoadedInSession;
|
if (alreadyLoadedInSession != null) return alreadyLoadedInSession;
|
||||||
|
|
||||||
StorageId storageId = new StorageId(id);
|
StorageId storageId = new StorageId(id);
|
||||||
return getUserByUsername(storageId.getExternalId(), realm);
|
return getUserByUsername(realm, storageId.getExternalId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -342,29 +345,20 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
|
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
return Stream.empty();
|
return Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
||||||
return searchForUserStream(search, realm, 0, Integer.MAX_VALUE - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
|
|
||||||
Map<String, String> attributes = new HashMap<String, String>();
|
Map<String, String> attributes = new HashMap<String, String>();
|
||||||
attributes.put(UserModel.SEARCH,search);
|
attributes.put(UserModel.SEARCH,search);
|
||||||
return searchForUserStream(attributes, realm, firstResult, maxResults);
|
return searchForUserStream(realm, attributes, firstResult, maxResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm) {
|
|
||||||
return searchForUserStream(params, realm, 0, Integer.MAX_VALUE - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params, Integer firstResult, Integer maxResults) {
|
||||||
String search = params.get(UserModel.SEARCH);
|
String search = params.get(UserModel.SEARCH);
|
||||||
if(search!=null) {
|
if(search!=null) {
|
||||||
int spaceIndex = search.lastIndexOf(' ');
|
int spaceIndex = search.lastIndexOf(' ');
|
||||||
|
@ -385,41 +379,34 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
Stream<LDAPObject> stream = searchLDAP(realm, params).stream()
|
Stream<LDAPObject> stream = searchLDAP(realm, params).stream()
|
||||||
.filter(ldapObject -> {
|
.filter(ldapObject -> {
|
||||||
String ldapUsername = LDAPUtils.getUsername(ldapObject, this.ldapIdentityStore.getConfig());
|
String ldapUsername = LDAPUtils.getUsername(ldapObject, this.ldapIdentityStore.getConfig());
|
||||||
return (session.userLocalStorage().getUserByUsername(ldapUsername, realm) == null);
|
return (session.userLocalStorage().getUserByUsername(realm, ldapUsername) == null);
|
||||||
});
|
});
|
||||||
if (firstResult > 0)
|
|
||||||
stream = stream.skip(firstResult);
|
|
||||||
if (maxResults >= 0)
|
|
||||||
stream = stream.limit(maxResults);
|
|
||||||
return stream.map(ldapObject -> importUserFromLDAP(session, realm, ldapObject));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
return paginatedStream(stream, firstResult, maxResults).map(ldapObject -> importUserFromLDAP(session, realm, ldapObject));
|
||||||
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
|
|
||||||
return getGroupMembersStream(realm, group, 0, Integer.MAX_VALUE - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
|
||||||
|
int first = firstResult == null ? 0 : firstResult;
|
||||||
|
int max = maxResults == null ? DEFAULT_MAX_RESULTS : maxResults;
|
||||||
|
|
||||||
return realm.getComponentsStream(model.getId(), LDAPStorageMapper.class.getName())
|
return realm.getComponentsStream(model.getId(), LDAPStorageMapper.class.getName())
|
||||||
.sorted(ldapMappersComparator.sortAsc())
|
.sorted(ldapMappersComparator.sortAsc())
|
||||||
.map(mapperModel ->
|
.map(mapperModel ->
|
||||||
mapperManager.getMapper(mapperModel).getGroupMembers(realm, group, firstResult, maxResults))
|
mapperManager.getMapper(mapperModel).getGroupMembers(realm, group, first, max))
|
||||||
.filter(((Predicate<List>) List::isEmpty).negate())
|
.filter(((Predicate<List>) List::isEmpty).negate())
|
||||||
.map(List::stream)
|
.map(List::stream)
|
||||||
.findFirst().orElse(Stream.empty());
|
.findFirst().orElse(Stream.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role) {
|
|
||||||
return getRoleMembersStream(realm, role, 0, Integer.MAX_VALUE - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults) {
|
||||||
|
int first = firstResult == null ? 0 : firstResult;
|
||||||
|
int max = maxResults == null ? DEFAULT_MAX_RESULTS : maxResults;
|
||||||
|
|
||||||
return realm.getComponentsStream(model.getId(), LDAPStorageMapper.class.getName())
|
return realm.getComponentsStream(model.getId(), LDAPStorageMapper.class.getName())
|
||||||
.sorted(ldapMappersComparator.sortAsc())
|
.sorted(ldapMappersComparator.sortAsc())
|
||||||
.map(mapperModel -> mapperManager.getMapper(mapperModel).getRoleMembers(realm, role, firstResult, maxResults))
|
.map(mapperModel -> mapperManager.getMapper(mapperModel).getRoleMembers(realm, role, first, max))
|
||||||
.filter(((Predicate<List>) List::isEmpty).negate())
|
.filter(((Predicate<List>) List::isEmpty).negate())
|
||||||
.map(List::stream)
|
.map(List::stream)
|
||||||
.findFirst().orElse(Stream.empty());
|
.findFirst().orElse(Stream.empty());
|
||||||
|
@ -428,7 +415,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
public List<UserModel> loadUsersByUsernames(List<String> usernames, RealmModel realm) {
|
public List<UserModel> loadUsersByUsernames(List<String> usernames, RealmModel realm) {
|
||||||
List<UserModel> result = new ArrayList<>();
|
List<UserModel> result = new ArrayList<>();
|
||||||
for (String username : usernames) {
|
for (String username : usernames) {
|
||||||
UserModel kcUser = session.users().getUserByUsername(username, realm);
|
UserModel kcUser = session.users().getUserByUsername(realm, username);
|
||||||
if (kcUser == null) {
|
if (kcUser == null) {
|
||||||
logger.warnf("User '%s' referenced by membership wasn't found in LDAP", username);
|
logger.warnf("User '%s' referenced by membership wasn't found in LDAP", username);
|
||||||
} else if (model.isImportEnabled() && !model.getId().equals(kcUser.getFederationLink())) {
|
} else if (model.isImportEnabled() && !model.getId().equals(kcUser.getFederationLink())) {
|
||||||
|
@ -514,7 +501,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
public UserModel getUserByUsername(RealmModel realm, String username) {
|
||||||
LDAPObject ldapUser = loadLDAPUserByUsername(realm, username);
|
LDAPObject ldapUser = loadLDAPUserByUsername(realm, username);
|
||||||
if (ldapUser == null) {
|
if (ldapUser == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -575,7 +562,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
public UserModel getUserByEmail(RealmModel realm, String email) {
|
||||||
LDAPObject ldapUser = queryByEmail(realm, email);
|
LDAPObject ldapUser = queryByEmail(realm, email);
|
||||||
if (ldapUser == null) {
|
if (ldapUser == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -583,7 +570,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
|
|
||||||
// Check here if user already exists
|
// Check here if user already exists
|
||||||
String ldapUsername = LDAPUtils.getUsername(ldapUser, ldapIdentityStore.getConfig());
|
String ldapUsername = LDAPUtils.getUsername(ldapUser, ldapIdentityStore.getConfig());
|
||||||
UserModel user = session.userLocalStorage().getUserByUsername(ldapUsername, realm);
|
UserModel user = session.userLocalStorage().getUserByUsername(realm, ldapUsername);
|
||||||
|
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
LDAPUtils.checkUuid(ldapUser, ldapIdentityStore.getConfig());
|
LDAPUtils.checkUuid(ldapUser, ldapIdentityStore.getConfig());
|
||||||
|
@ -771,7 +758,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
* @return finded or newly created user
|
* @return finded or newly created user
|
||||||
*/
|
*/
|
||||||
protected UserModel findOrCreateAuthenticatedUser(RealmModel realm, String username) {
|
protected UserModel findOrCreateAuthenticatedUser(RealmModel realm, String username) {
|
||||||
UserModel user = session.userLocalStorage().getUserByUsername(username, realm);
|
UserModel user = session.userLocalStorage().getUserByUsername(realm, username);
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
logger.debugf("Kerberos authenticated user [%s] found in Keycloak storage", username);
|
logger.debugf("Kerberos authenticated user [%s] found in Keycloak storage", username);
|
||||||
if (!model.getId().equals(user.getFederationLink())) {
|
if (!model.getId().equals(user.getFederationLink())) {
|
||||||
|
@ -796,7 +783,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
|
|
||||||
// Creating user to local storage
|
// Creating user to local storage
|
||||||
logger.debugf("Kerberos authenticated user [%s] not in Keycloak storage. Creating him", username);
|
logger.debugf("Kerberos authenticated user [%s] not in Keycloak storage. Creating him", username);
|
||||||
return getUserByUsername(username, realm);
|
return getUserByUsername(realm, username);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LDAPObject loadLDAPUserByUsername(RealmModel realm, String username) {
|
public LDAPObject loadLDAPUserByUsername(RealmModel realm, String username) {
|
||||||
|
|
|
@ -593,7 +593,7 @@ public class LDAPStorageProviderFactory implements UserStorageProviderFactory<LD
|
||||||
String username = LDAPUtils.getUsername(ldapUser, ldapFedProvider.getLdapIdentityStore().getConfig());
|
String username = LDAPUtils.getUsername(ldapUser, ldapFedProvider.getLdapIdentityStore().getConfig());
|
||||||
exists.value = true;
|
exists.value = true;
|
||||||
LDAPUtils.checkUuid(ldapUser, ldapFedProvider.getLdapIdentityStore().getConfig());
|
LDAPUtils.checkUuid(ldapUser, ldapFedProvider.getLdapIdentityStore().getConfig());
|
||||||
UserModel currentUser = session.userLocalStorage().getUserByUsername(username, currentRealm);
|
UserModel currentUser = session.userLocalStorage().getUserByUsername(currentRealm, username);
|
||||||
|
|
||||||
if (currentUser == null) {
|
if (currentUser == null) {
|
||||||
|
|
||||||
|
@ -649,7 +649,7 @@ public class LDAPStorageProviderFactory implements UserStorageProviderFactory<LD
|
||||||
}
|
}
|
||||||
|
|
||||||
if (username != null) {
|
if (username != null) {
|
||||||
UserModel existing = session.userLocalStorage().getUserByUsername(username, currentRealm);
|
UserModel existing = session.userLocalStorage().getUserByUsername(currentRealm, username);
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
UserCache userCache = session.userCache();
|
UserCache userCache = session.userCache();
|
||||||
if (userCache != null) {
|
if (userCache != null) {
|
||||||
|
|
|
@ -149,7 +149,7 @@ public class UserAttributeLDAPStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
// lowercase before search
|
// lowercase before search
|
||||||
email = KeycloakModelUtils.toLowerCaseSafe(email);
|
email = KeycloakModelUtils.toLowerCaseSafe(email);
|
||||||
|
|
||||||
UserModel that = session.userLocalStorage().getUserByEmail(email, realm);
|
UserModel that = session.userLocalStorage().getUserByEmail(realm, email);
|
||||||
if (that != null && !that.getId().equals(user.getId())) {
|
if (that != null && !that.getId().equals(user.getId())) {
|
||||||
session.getTransactionManager().setRollbackOnly();
|
session.getTransactionManager().setRollbackOnly();
|
||||||
String exceptionMessage = String.format("Can't import user '%s' from LDAP because email '%s' already exists in Keycloak. Existing user with this email is '%s'", user.getUsername(), email, that.getUsername());
|
String exceptionMessage = String.format("Can't import user '%s' from LDAP because email '%s' already exists in Keycloak. Existing user with this email is '%s'", user.getUsername(), email, that.getUsername());
|
||||||
|
@ -166,7 +166,7 @@ public class UserAttributeLDAPStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
}
|
}
|
||||||
boolean usernameChanged = !username.equals(user.getUsername());
|
boolean usernameChanged = !username.equals(user.getUsername());
|
||||||
if (realm.isEditUsernameAllowed() && usernameChanged) {
|
if (realm.isEditUsernameAllowed() && usernameChanged) {
|
||||||
UserModel that = session.users().getUserByUsername(username, realm);
|
UserModel that = session.users().getUserByUsername(realm, username);
|
||||||
if (that != null && !that.getId().equals(user.getId())) {
|
if (that != null && !that.getId().equals(user.getId())) {
|
||||||
throw new ModelDuplicateException(
|
throw new ModelDuplicateException(
|
||||||
String.format("Cannot change the username to '%s' because the username already exists in keycloak", username),
|
String.format("Cannot change the username to '%s' because the username already exists in keycloak", username),
|
||||||
|
|
|
@ -44,7 +44,7 @@ import java.util.stream.Stream;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class SSSDFederationProvider implements UserStorageProvider,
|
public class SSSDFederationProvider implements UserStorageProvider,
|
||||||
UserLookupProvider,
|
UserLookupProvider.Streams,
|
||||||
CredentialInputUpdater.Streams,
|
CredentialInputUpdater.Streams,
|
||||||
CredentialInputValidator,
|
CredentialInputValidator,
|
||||||
ImportedUserValidation {
|
ImportedUserValidation {
|
||||||
|
@ -68,7 +68,7 @@ public class SSSDFederationProvider implements UserStorageProvider,
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
public UserModel getUserByUsername(RealmModel realm, String username) {
|
||||||
return findOrCreateAuthenticatedUser(realm, username);
|
return findOrCreateAuthenticatedUser(realm, username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ public class SSSDFederationProvider implements UserStorageProvider,
|
||||||
* @return user if found or successfully created. Null if user with same username already exists, but is not linked to this provider
|
* @return user if found or successfully created. Null if user with same username already exists, but is not linked to this provider
|
||||||
*/
|
*/
|
||||||
protected UserModel findOrCreateAuthenticatedUser(RealmModel realm, String username) {
|
protected UserModel findOrCreateAuthenticatedUser(RealmModel realm, String username) {
|
||||||
UserModel user = session.userLocalStorage().getUserByUsername(username, realm);
|
UserModel user = session.userLocalStorage().getUserByUsername(realm, username);
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
logger.debug("SSSD authenticated user " + username + " found in Keycloak storage");
|
logger.debug("SSSD authenticated user " + username + " found in Keycloak storage");
|
||||||
|
|
||||||
|
@ -130,12 +130,12 @@ public class SSSDFederationProvider implements UserStorageProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
public UserModel getUserById(RealmModel realm, String id) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
public UserModel getUserByEmail(RealmModel realm, String email) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -380,6 +380,6 @@ public class UserAdapter implements CachedUserModel.Streams {
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserModel getUserModel() {
|
private UserModel getUserModel() {
|
||||||
return userProviderCache.getDelegate().getUserById(cached.getId(), realm);
|
return userProviderCache.getDelegate().getUserById(realm, cached.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,11 +183,11 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
public UserModel getUserById(RealmModel realm, String id) {
|
||||||
logger.tracev("getuserById {0}", id);
|
logger.tracev("getuserById {0}", id);
|
||||||
if (isRegisteredForInvalidation(realm, id)) {
|
if (isRegisteredForInvalidation(realm, id)) {
|
||||||
logger.trace("registered for invalidation return delegate");
|
logger.trace("registered for invalidation return delegate");
|
||||||
return getDelegate().getUserById(id, realm);
|
return getDelegate().getUserById(realm, id);
|
||||||
}
|
}
|
||||||
if (managedUsers.containsKey(id)) {
|
if (managedUsers.containsKey(id)) {
|
||||||
logger.trace("return managedusers");
|
logger.trace("return managedusers");
|
||||||
|
@ -204,7 +204,7 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
if (cached == null) {
|
if (cached == null) {
|
||||||
logger.trace("not cached");
|
logger.trace("not cached");
|
||||||
Long loaded = cache.getCurrentRevision(id);
|
Long loaded = cache.getCurrentRevision(id);
|
||||||
UserModel delegate = getDelegate().getUserById(id, realm);
|
UserModel delegate = getDelegate().getUserById(realm, id);
|
||||||
if (delegate == null) {
|
if (delegate == null) {
|
||||||
logger.trace("delegate returning null");
|
logger.trace("delegate returning null");
|
||||||
return null;
|
return null;
|
||||||
|
@ -238,17 +238,17 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
public UserModel getUserByUsername(RealmModel realm, String username) {
|
||||||
logger.tracev("getUserByUsername: {0}", username);
|
logger.tracev("getUserByUsername: {0}", username);
|
||||||
username = username.toLowerCase();
|
username = username.toLowerCase();
|
||||||
if (realmInvalidations.contains(realm.getId())) {
|
if (realmInvalidations.contains(realm.getId())) {
|
||||||
logger.tracev("realmInvalidations");
|
logger.tracev("realmInvalidations");
|
||||||
return getDelegate().getUserByUsername(username, realm);
|
return getDelegate().getUserByUsername(realm, username);
|
||||||
}
|
}
|
||||||
String cacheKey = getUserByUsernameCacheKey(realm.getId(), username);
|
String cacheKey = getUserByUsernameCacheKey(realm.getId(), username);
|
||||||
if (invalidations.contains(cacheKey)) {
|
if (invalidations.contains(cacheKey)) {
|
||||||
logger.tracev("invalidations");
|
logger.tracev("invalidations");
|
||||||
return getDelegate().getUserByUsername(username, realm);
|
return getDelegate().getUserByUsername(realm, username);
|
||||||
}
|
}
|
||||||
UserListQuery query = cache.get(cacheKey, UserListQuery.class);
|
UserListQuery query = cache.get(cacheKey, UserListQuery.class);
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
logger.tracev("query null");
|
logger.tracev("query null");
|
||||||
Long loaded = cache.getCurrentRevision(cacheKey);
|
Long loaded = cache.getCurrentRevision(cacheKey);
|
||||||
UserModel model = getDelegate().getUserByUsername(username, realm);
|
UserModel model = getDelegate().getUserByUsername(realm, username);
|
||||||
if (model == null) {
|
if (model == null) {
|
||||||
logger.tracev("model from delegate null");
|
logger.tracev("model from delegate null");
|
||||||
return null;
|
return null;
|
||||||
|
@ -279,11 +279,11 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
userId = query.getUsers().iterator().next();
|
userId = query.getUsers().iterator().next();
|
||||||
if (invalidations.contains(userId)) {
|
if (invalidations.contains(userId)) {
|
||||||
logger.tracev("invalidated cache return delegate");
|
logger.tracev("invalidated cache return delegate");
|
||||||
return getDelegate().getUserByUsername(username, realm);
|
return getDelegate().getUserByUsername(realm, username);
|
||||||
|
|
||||||
}
|
}
|
||||||
logger.trace("return getUserById");
|
logger.trace("return getUserById");
|
||||||
return getUserById(userId, realm);
|
return getUserById(realm, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
// its also hard to test stuff
|
// its also hard to test stuff
|
||||||
if (model.shouldInvalidate(cached)) {
|
if (model.shouldInvalidate(cached)) {
|
||||||
registerUserInvalidation(realm, cached);
|
registerUserInvalidation(realm, cached);
|
||||||
return getDelegate().getUserById(cached.getId(), realm);
|
return getDelegate().getUserById(realm, cached.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new UserAdapter(cached, this, session, realm);
|
return new UserAdapter(cached, this, session, realm);
|
||||||
|
@ -368,22 +368,22 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
public UserModel getUserByEmail(RealmModel realm, String email) {
|
||||||
if (email == null) return null;
|
if (email == null) return null;
|
||||||
email = email.toLowerCase();
|
email = email.toLowerCase();
|
||||||
if (realmInvalidations.contains(realm.getId())) {
|
if (realmInvalidations.contains(realm.getId())) {
|
||||||
return getDelegate().getUserByEmail(email, realm);
|
return getDelegate().getUserByEmail(realm, email);
|
||||||
}
|
}
|
||||||
String cacheKey = getUserByEmailCacheKey(realm.getId(), email);
|
String cacheKey = getUserByEmailCacheKey(realm.getId(), email);
|
||||||
if (invalidations.contains(cacheKey)) {
|
if (invalidations.contains(cacheKey)) {
|
||||||
return getDelegate().getUserByEmail(email, realm);
|
return getDelegate().getUserByEmail(realm, email);
|
||||||
}
|
}
|
||||||
UserListQuery query = cache.get(cacheKey, UserListQuery.class);
|
UserListQuery query = cache.get(cacheKey, UserListQuery.class);
|
||||||
|
|
||||||
String userId = null;
|
String userId = null;
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
Long loaded = cache.getCurrentRevision(cacheKey);
|
Long loaded = cache.getCurrentRevision(cacheKey);
|
||||||
UserModel model = getDelegate().getUserByEmail(email, realm);
|
UserModel model = getDelegate().getUserByEmail(realm, email);
|
||||||
if (model == null) return null;
|
if (model == null) return null;
|
||||||
userId = model.getId();
|
userId = model.getId();
|
||||||
if (invalidations.contains(userId)) return model;
|
if (invalidations.contains(userId)) return model;
|
||||||
|
@ -399,10 +399,10 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
} else {
|
} else {
|
||||||
userId = query.getUsers().iterator().next();
|
userId = query.getUsers().iterator().next();
|
||||||
if (invalidations.contains(userId)) {
|
if (invalidations.contains(userId)) {
|
||||||
return getDelegate().getUserByEmail(email, realm);
|
return getDelegate().getUserByEmail(realm, email);
|
||||||
|
|
||||||
}
|
}
|
||||||
return getUserById(userId, realm);
|
return getUserById(realm, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,23 +412,23 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm) {
|
public UserModel getUserByFederatedIdentity(RealmModel realm, FederatedIdentityModel socialLink) {
|
||||||
if (socialLink == null) return null;
|
if (socialLink == null) return null;
|
||||||
if (!realm.isIdentityFederationEnabled()) return null;
|
if (!realm.isIdentityFederationEnabled()) return null;
|
||||||
|
|
||||||
if (realmInvalidations.contains(realm.getId())) {
|
if (realmInvalidations.contains(realm.getId())) {
|
||||||
return getDelegate().getUserByFederatedIdentity(socialLink, realm);
|
return getDelegate().getUserByFederatedIdentity(realm, socialLink);
|
||||||
}
|
}
|
||||||
String cacheKey = getUserByFederatedIdentityCacheKey(realm.getId(), socialLink);
|
String cacheKey = getUserByFederatedIdentityCacheKey(realm.getId(), socialLink);
|
||||||
if (invalidations.contains(cacheKey)) {
|
if (invalidations.contains(cacheKey)) {
|
||||||
return getDelegate().getUserByFederatedIdentity(socialLink, realm);
|
return getDelegate().getUserByFederatedIdentity(realm, socialLink);
|
||||||
}
|
}
|
||||||
UserListQuery query = cache.get(cacheKey, UserListQuery.class);
|
UserListQuery query = cache.get(cacheKey, UserListQuery.class);
|
||||||
|
|
||||||
String userId = null;
|
String userId = null;
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
Long loaded = cache.getCurrentRevision(cacheKey);
|
Long loaded = cache.getCurrentRevision(cacheKey);
|
||||||
UserModel model = getDelegate().getUserByFederatedIdentity(socialLink, realm);
|
UserModel model = getDelegate().getUserByFederatedIdentity(realm, socialLink);
|
||||||
if (model == null) return null;
|
if (model == null) return null;
|
||||||
userId = model.getId();
|
userId = model.getId();
|
||||||
if (invalidations.contains(userId)) return model;
|
if (invalidations.contains(userId)) return model;
|
||||||
|
@ -446,10 +446,10 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
userId = query.getUsers().iterator().next();
|
userId = query.getUsers().iterator().next();
|
||||||
if (invalidations.contains(userId)) {
|
if (invalidations.contains(userId)) {
|
||||||
invalidations.add(cacheKey);
|
invalidations.add(cacheKey);
|
||||||
return getDelegate().getUserByFederatedIdentity(socialLink, realm);
|
return getDelegate().getUserByFederatedIdentity(realm, socialLink);
|
||||||
|
|
||||||
}
|
}
|
||||||
return getUserById(userId, realm);
|
return getUserById(realm, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,11 +527,11 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
userId = query.getUsers().iterator().next();
|
userId = query.getUsers().iterator().next();
|
||||||
if (invalidations.contains(userId)) {
|
if (invalidations.contains(userId)) {
|
||||||
logger.tracev("invalidated cache return delegate");
|
logger.tracev("invalidated cache return delegate");
|
||||||
return getDelegate().getUserByUsername(username, realm);
|
return getDelegate().getUserByUsername(realm, username);
|
||||||
|
|
||||||
}
|
}
|
||||||
logger.trace("return getUserById");
|
logger.trace("return getUserById");
|
||||||
return getUserById(userId, realm);
|
return getUserById(realm, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,34 +545,29 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
return getDelegate().getUsersCount(realm, includeServiceAccount);
|
return getDelegate().getUsersCount(realm, includeServiceAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getUsersCount(RealmModel realm) {
|
|
||||||
return getUsersCount(realm, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(RealmModel realm, Set<String> groupIds) {
|
public int getUsersCount(RealmModel realm, Set<String> groupIds) {
|
||||||
return getDelegate().getUsersCount(realm, groupIds);
|
return getDelegate().getUsersCount(realm, groupIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(String search, RealmModel realm) {
|
public int getUsersCount(RealmModel realm, String search) {
|
||||||
return getDelegate().getUsersCount(search, realm);
|
return getDelegate().getUsersCount(realm, search);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(String search, RealmModel realm, Set<String> groupIds) {
|
public int getUsersCount(RealmModel realm, String search, Set<String> groupIds) {
|
||||||
return getDelegate().getUsersCount(search, realm, groupIds);
|
return getDelegate().getUsersCount(realm, search, groupIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(Map<String, String> params, RealmModel realm) {
|
public int getUsersCount(RealmModel realm, Map<String, String> params) {
|
||||||
return getDelegate().getUsersCount(params, realm);
|
return getDelegate().getUsersCount(realm, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(Map<String, String> params, RealmModel realm, Set<String> groupIds) {
|
public int getUsersCount(RealmModel realm, Map<String, String> params, Set<String> groupIds) {
|
||||||
return getDelegate().getUsersCount(params, realm, groupIds);
|
return getDelegate().getUsersCount(realm, params, groupIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -586,49 +581,49 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
|
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
return getUsersStream(realm, firstResult, maxResults, false);
|
return getUsersStream(realm, firstResult, maxResults, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search) {
|
||||||
return getDelegate().searchForUserStream(search, realm);
|
return getDelegate().searchForUserStream(realm, search);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
||||||
return getDelegate().searchForUserStream(search, realm, firstResult, maxResults);
|
return getDelegate().searchForUserStream(realm, search, firstResult, maxResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes) {
|
||||||
return getDelegate().searchForUserStream(attributes, realm);
|
return getDelegate().searchForUserStream(realm, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes, Integer firstResult, Integer maxResults) {
|
||||||
return getDelegate().searchForUserStream(attributes, realm, firstResult, maxResults);
|
return getDelegate().searchForUserStream(realm, attributes, firstResult, maxResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
|
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
|
||||||
return getDelegate().searchForUserByUserAttributeStream(attrName, attrValue, realm);
|
return getDelegate().searchForUserByUserAttributeStream(realm, attrName, attrValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm) {
|
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel realm, UserModel user) {
|
||||||
logger.tracev("getFederatedIdentities: {0}", user.getUsername());
|
logger.tracev("getFederatedIdentities: {0}", user.getUsername());
|
||||||
|
|
||||||
String cacheKey = getFederatedIdentityLinksCacheKey(user.getId());
|
String cacheKey = getFederatedIdentityLinksCacheKey(user.getId());
|
||||||
if (realmInvalidations.contains(realm.getId()) || invalidations.contains(user.getId()) || invalidations.contains(cacheKey)) {
|
if (realmInvalidations.contains(realm.getId()) || invalidations.contains(user.getId()) || invalidations.contains(cacheKey)) {
|
||||||
return getDelegate().getFederatedIdentitiesStream(user, realm);
|
return getDelegate().getFederatedIdentitiesStream(realm, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
CachedFederatedIdentityLinks cachedLinks = cache.get(cacheKey, CachedFederatedIdentityLinks.class);
|
CachedFederatedIdentityLinks cachedLinks = cache.get(cacheKey, CachedFederatedIdentityLinks.class);
|
||||||
|
|
||||||
if (cachedLinks == null) {
|
if (cachedLinks == null) {
|
||||||
Long loaded = cache.getCurrentRevision(cacheKey);
|
Long loaded = cache.getCurrentRevision(cacheKey);
|
||||||
Set<FederatedIdentityModel> federatedIdentities = getDelegate().getFederatedIdentitiesStream(user, realm)
|
Set<FederatedIdentityModel> federatedIdentities = getDelegate().getFederatedIdentitiesStream(realm, user)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
cachedLinks = new CachedFederatedIdentityLinks(loaded, cacheKey, realm, federatedIdentities);
|
cachedLinks = new CachedFederatedIdentityLinks(loaded, cacheKey, realm, federatedIdentities);
|
||||||
cache.addRevisioned(cachedLinks, startupRevision);
|
cache.addRevisioned(cachedLinks, startupRevision);
|
||||||
|
@ -639,15 +634,15 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm) {
|
public FederatedIdentityModel getFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
|
||||||
logger.tracev("getFederatedIdentity: {0} {1}", user.getUsername(), socialProvider);
|
logger.tracev("getFederatedIdentity: {0} {1}", user.getUsername(), socialProvider);
|
||||||
|
|
||||||
String cacheKey = getFederatedIdentityLinksCacheKey(user.getId());
|
String cacheKey = getFederatedIdentityLinksCacheKey(user.getId());
|
||||||
if (realmInvalidations.contains(realm.getId()) || invalidations.contains(user.getId()) || invalidations.contains(cacheKey)) {
|
if (realmInvalidations.contains(realm.getId()) || invalidations.contains(user.getId()) || invalidations.contains(cacheKey)) {
|
||||||
return getDelegate().getFederatedIdentity(user, socialProvider, realm);
|
return getDelegate().getFederatedIdentity(realm, user, socialProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getFederatedIdentitiesStream(user, realm)
|
return getFederatedIdentitiesStream(realm, user)
|
||||||
.filter(socialLink -> Objects.equals(socialLink.getIdentityProvider(), socialProvider))
|
.filter(socialLink -> Objects.equals(socialLink.getIdentityProvider(), socialProvider))
|
||||||
.findFirst().orElse(null);
|
.findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
|
@ -748,7 +743,7 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
@Override
|
@Override
|
||||||
public void setNotBeforeForUser(RealmModel realm, UserModel user, int notBefore) {
|
public void setNotBeforeForUser(RealmModel realm, UserModel user, int notBefore) {
|
||||||
if (!isRegisteredForInvalidation(realm, user.getId())) {
|
if (!isRegisteredForInvalidation(realm, user.getId())) {
|
||||||
UserModel foundUser = getUserById(user.getId(), realm);
|
UserModel foundUser = getUserById(realm, user.getId());
|
||||||
if (foundUser instanceof UserAdapter) {
|
if (foundUser instanceof UserAdapter) {
|
||||||
((UserAdapter) foundUser).invalidate();
|
((UserAdapter) foundUser).invalidate();
|
||||||
}
|
}
|
||||||
|
@ -764,7 +759,7 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
return getDelegate().getNotBeforeOfUser(realm, user);
|
return getDelegate().getNotBeforeOfUser(realm, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserModel foundUser = getUserById(user.getId(), realm);
|
UserModel foundUser = getUserById(realm, user.getId());
|
||||||
if (foundUser instanceof UserAdapter) {
|
if (foundUser instanceof UserAdapter) {
|
||||||
return ((UserAdapter) foundUser).cached.getNotBefore();
|
return ((UserAdapter) foundUser).cached.getNotBefore();
|
||||||
} else {
|
} else {
|
||||||
|
@ -793,7 +788,7 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
// just in case the transaction is rolled back you need to invalidate the user and all cache queries for that user
|
// just in case the transaction is rolled back you need to invalidate the user and all cache queries for that user
|
||||||
protected void fullyInvalidateUser(RealmModel realm, UserModel user) {
|
protected void fullyInvalidateUser(RealmModel realm, UserModel user) {
|
||||||
Stream<FederatedIdentityModel> federatedIdentities = realm.isIdentityFederationEnabled() ?
|
Stream<FederatedIdentityModel> federatedIdentities = realm.isIdentityFederationEnabled() ?
|
||||||
getFederatedIdentitiesStream(user, realm) : Stream.empty();
|
getFederatedIdentitiesStream(realm, user) : Stream.empty();
|
||||||
|
|
||||||
UserFullInvalidationEvent event = UserFullInvalidationEvent.create(user.getId(), user.getUsername(), user.getEmail(), realm.getId(), realm.isIdentityFederationEnabled(), federatedIdentities);
|
UserFullInvalidationEvent event = UserFullInvalidationEvent.create(user.getId(), user.getUsername(), user.getEmail(), realm.getId(), realm.isIdentityFederationEnabled(), federatedIdentities);
|
||||||
|
|
||||||
|
@ -827,7 +822,7 @@ public class UserCacheSession implements UserCache.Streams {
|
||||||
@Override
|
@Override
|
||||||
public boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
|
public boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
|
||||||
// Needs to invalidate both directions
|
// Needs to invalidate both directions
|
||||||
FederatedIdentityModel socialLink = getFederatedIdentity(user, socialProvider, realm);
|
FederatedIdentityModel socialLink = getFederatedIdentity(realm, user, socialProvider);
|
||||||
|
|
||||||
UserFederationLinkRemovedEvent event = UserFederationLinkRemovedEvent.create(user.getId(), realm.getId(), socialLink);
|
UserFederationLinkRemovedEvent event = UserFederationLinkRemovedEvent.create(user.getId(), realm.getId(), socialLink);
|
||||||
cache.federatedIdentityLinkRemovedInvalidation(user.getId(), realm.getId(), event.getIdentityProviderId(), event.getSocialUserId(), invalidations);
|
cache.federatedIdentityLinkRemovedInvalidation(user.getId(), realm.getId(), event.getIdentityProviderId(), event.getSocialUserId(), invalidations);
|
||||||
|
|
|
@ -282,7 +282,7 @@ public class AuthenticationSessionAdapter implements AuthenticationSessionModel
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getAuthenticatedUser() {
|
public UserModel getAuthenticatedUser() {
|
||||||
return entity.getAuthUserId() == null ? null : session.users().getUserById(entity.getAuthUserId(), getRealm()); }
|
return entity.getAuthUserId() == null ? null : session.users().getUserById(getRealm(), entity.getAuthUserId()); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAuthenticatedUser(UserModel user) {
|
public void setAuthenticatedUser(UserModel user) {
|
||||||
|
|
|
@ -175,7 +175,7 @@ public class UserSessionAdapter implements UserSessionModel {
|
||||||
return entity.getBrokerUserId();
|
return entity.getBrokerUserId();
|
||||||
}
|
}
|
||||||
public UserModel getUser() {
|
public UserModel getUser() {
|
||||||
return session.users().getUserById(entity.getUser(), realm);
|
return session.users().getUserById(realm, entity.getUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -57,6 +57,7 @@ import java.util.stream.Stream;
|
||||||
import org.keycloak.models.ModelException;
|
import org.keycloak.models.ModelException;
|
||||||
|
|
||||||
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
|
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
|
||||||
|
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
|
||||||
import static org.keycloak.utils.StreamsUtil.closing;
|
import static org.keycloak.utils.StreamsUtil.closing;
|
||||||
|
|
||||||
|
|
||||||
|
@ -288,12 +289,7 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Stream<RoleModel> getRolesStream(TypedQuery<RoleEntity> query, RealmModel realm, Integer first, Integer max) {
|
protected Stream<RoleModel> getRolesStream(TypedQuery<RoleEntity> query, RealmModel realm, Integer first, Integer max) {
|
||||||
if(Objects.nonNull(first) && Objects.nonNull(max)
|
Stream<RoleEntity> results = paginateQuery(query, first, max).getResultStream();
|
||||||
&& first >= 0 && max >= 0) {
|
|
||||||
query= query.setFirstResult(first).setMaxResults(max);
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream<RoleEntity> results = query.getResultStream();
|
|
||||||
|
|
||||||
return closing(results.map(role -> new RoleAdapter(session, realm, em, role)));
|
return closing(results.map(role -> new RoleAdapter(session, realm, em, role)));
|
||||||
}
|
}
|
||||||
|
@ -452,18 +448,6 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
|
||||||
.map(g -> session.groups().getGroupById(realm, g));
|
.map(g -> session.groups().getGroupById(realm, g));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> TypedQuery<T> paginateQuery(TypedQuery<T> query, Integer first, Integer max) {
|
|
||||||
if (first != null && first > 0) {
|
|
||||||
query = query.setFirstResult(first);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max != null && max >= 0) {
|
|
||||||
query = query.setMaxResults(max);
|
|
||||||
}
|
|
||||||
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<GroupModel> getGroupsStream(RealmModel realm, Stream<String> ids) {
|
public Stream<GroupModel> getGroupsStream(RealmModel realm, Stream<String> ids) {
|
||||||
return ids.map(id -> session.groups().getGroupById(realm, id)).sorted(GroupModel.COMPARE_BY_NAME);
|
return ids.map(id -> session.groups().getGroupById(realm, id)).sorted(GroupModel.COMPARE_BY_NAME);
|
||||||
|
@ -515,13 +499,8 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
|
||||||
public Stream<GroupModel> getGroupsByRoleStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults) {
|
public Stream<GroupModel> getGroupsByRoleStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults) {
|
||||||
TypedQuery<GroupEntity> query = em.createNamedQuery("groupsInRole", GroupEntity.class);
|
TypedQuery<GroupEntity> query = em.createNamedQuery("groupsInRole", GroupEntity.class);
|
||||||
query.setParameter("roleId", role.getId());
|
query.setParameter("roleId", role.getId());
|
||||||
if (firstResult != null && firstResult > 0) {
|
|
||||||
query = query.setFirstResult(firstResult);
|
Stream<GroupEntity> results = paginateQuery(query, firstResult, maxResults).getResultStream();
|
||||||
}
|
|
||||||
if (maxResults != null && maxResults > 0) {
|
|
||||||
query = query.setMaxResults(maxResults);
|
|
||||||
}
|
|
||||||
Stream<GroupEntity> results = query.getResultStream();
|
|
||||||
|
|
||||||
return closing(results
|
return closing(results
|
||||||
.map(g -> (GroupModel) new GroupAdapter(realm, em, g))
|
.map(g -> (GroupModel) new GroupAdapter(realm, em, g))
|
||||||
|
@ -657,14 +636,9 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
|
||||||
@Override
|
@Override
|
||||||
public Stream<ClientModel> getClientsStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
public Stream<ClientModel> getClientsStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
TypedQuery<String> query = em.createNamedQuery("getClientIdsByRealm", String.class);
|
TypedQuery<String> query = em.createNamedQuery("getClientIdsByRealm", String.class);
|
||||||
if (firstResult != null && firstResult > 0) {
|
|
||||||
query.setFirstResult(firstResult);
|
|
||||||
}
|
|
||||||
if (maxResults != null && maxResults > 0) {
|
|
||||||
query.setMaxResults(maxResults);
|
|
||||||
}
|
|
||||||
query.setParameter("realm", realm.getId());
|
query.setParameter("realm", realm.getId());
|
||||||
Stream<String> clients = query.getResultStream();
|
Stream<String> clients = paginateQuery(query, firstResult, maxResults).getResultStream();
|
||||||
|
|
||||||
return closing(clients.map(c -> session.clients().getClientById(realm, c)).filter(Objects::nonNull));
|
return closing(clients.map(c -> session.clients().getClientById(realm, c)).filter(Objects::nonNull));
|
||||||
}
|
}
|
||||||
|
@ -706,15 +680,10 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
|
||||||
@Override
|
@Override
|
||||||
public Stream<ClientModel> searchClientsByClientIdStream(RealmModel realm, String clientId, Integer firstResult, Integer maxResults) {
|
public Stream<ClientModel> searchClientsByClientIdStream(RealmModel realm, String clientId, Integer firstResult, Integer maxResults) {
|
||||||
TypedQuery<String> query = em.createNamedQuery("searchClientsByClientId", String.class);
|
TypedQuery<String> query = em.createNamedQuery("searchClientsByClientId", String.class);
|
||||||
if (firstResult != null && firstResult > 0) {
|
|
||||||
query.setFirstResult(firstResult);
|
|
||||||
}
|
|
||||||
if (maxResults != null && maxResults > 0) {
|
|
||||||
query.setMaxResults(maxResults);
|
|
||||||
}
|
|
||||||
query.setParameter("clientId", clientId);
|
query.setParameter("clientId", clientId);
|
||||||
query.setParameter("realm", realm.getId());
|
query.setParameter("realm", realm.getId());
|
||||||
Stream<String> results = query.getResultStream();
|
|
||||||
|
Stream<String> results = paginateQuery(query, firstResult, maxResults).getResultStream();
|
||||||
return closing(results.map(c -> session.clients().getClientById(realm, c)));
|
return closing(results.map(c -> session.clients().getClientById(realm, c)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,12 +65,12 @@ import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.persistence.LockModeType;
|
import javax.persistence.LockModeType;
|
||||||
|
|
||||||
|
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
|
||||||
import static org.keycloak.utils.StreamsUtil.closing;
|
import static org.keycloak.utils.StreamsUtil.closing;
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,18 +97,6 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
credentialStore = new JpaUserCredentialStore(session, em);
|
credentialStore = new JpaUserCredentialStore(session, em);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> TypedQuery<T> paginateQuery(TypedQuery<T> query, Integer first, Integer max) {
|
|
||||||
if (first != null && first > 0) {
|
|
||||||
query = query.setFirstResult(first);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max != null && max >= 0) {
|
|
||||||
query = query.setMaxResults(max);
|
|
||||||
}
|
|
||||||
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions) {
|
public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions) {
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
|
@ -364,12 +352,18 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
@Override
|
@Override
|
||||||
public void setNotBeforeForUser(RealmModel realm, UserModel user, int notBefore) {
|
public void setNotBeforeForUser(RealmModel realm, UserModel user, int notBefore) {
|
||||||
UserEntity entity = em.getReference(UserEntity.class, user.getId());
|
UserEntity entity = em.getReference(UserEntity.class, user.getId());
|
||||||
|
if (entity == null) {
|
||||||
|
throw new ModelException("User does not exists");
|
||||||
|
}
|
||||||
entity.setNotBefore(notBefore);
|
entity.setNotBefore(notBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNotBeforeOfUser(RealmModel realm, UserModel user) {
|
public int getNotBeforeOfUser(RealmModel realm, UserModel user) {
|
||||||
UserEntity entity = em.getReference(UserEntity.class, user.getId());
|
UserEntity entity = em.getReference(UserEntity.class, user.getId());
|
||||||
|
if (entity == null) {
|
||||||
|
throw new ModelException("User does not exists");
|
||||||
|
}
|
||||||
return entity.getNotBefore();
|
return entity.getNotBefore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,14 +508,14 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
public UserModel getUserById(RealmModel realm, String id) {
|
||||||
UserEntity userEntity = em.find(UserEntity.class, id);
|
UserEntity userEntity = em.find(UserEntity.class, id);
|
||||||
if (userEntity == null || !realm.getId().equals(userEntity.getRealmId())) return null;
|
if (userEntity == null || !realm.getId().equals(userEntity.getRealmId())) return null;
|
||||||
return new UserAdapter(session, realm, em, userEntity);
|
return new UserAdapter(session, realm, em, userEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
public UserModel getUserByUsername(RealmModel realm, String username) {
|
||||||
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByUsername", UserEntity.class);
|
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByUsername", UserEntity.class);
|
||||||
query.setParameter("username", username.toLowerCase());
|
query.setParameter("username", username.toLowerCase());
|
||||||
query.setParameter("realmId", realm.getId());
|
query.setParameter("realmId", realm.getId());
|
||||||
|
@ -531,7 +525,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
public UserModel getUserByEmail(RealmModel realm, String email) {
|
||||||
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByEmail", UserEntity.class);
|
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByEmail", UserEntity.class);
|
||||||
query.setParameter("email", email.toLowerCase());
|
query.setParameter("email", email.toLowerCase());
|
||||||
query.setParameter("realmId", realm.getId());
|
query.setParameter("realmId", realm.getId());
|
||||||
|
@ -549,7 +543,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByFederatedIdentity(FederatedIdentityModel identity, RealmModel realm) {
|
public UserModel getUserByFederatedIdentity(RealmModel realm, FederatedIdentityModel identity) {
|
||||||
TypedQuery<UserEntity> query = em.createNamedQuery("findUserByFederatedIdentityAndRealm", UserEntity.class);
|
TypedQuery<UserEntity> query = em.createNamedQuery("findUserByFederatedIdentityAndRealm", UserEntity.class);
|
||||||
query.setParameter("realmId", realm.getId());
|
query.setParameter("realmId", realm.getId());
|
||||||
query.setParameter("identityProvider", identity.getIdentityProvider());
|
query.setParameter("identityProvider", identity.getIdentityProvider());
|
||||||
|
@ -583,11 +577,6 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts) {
|
|
||||||
return getUsersStream(realm, -1, -1, includeServiceAccounts);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(RealmModel realm, boolean includeServiceAccount) {
|
public int getUsersCount(RealmModel realm, boolean includeServiceAccount) {
|
||||||
String namedQuery = "getRealmUserCountExcludeServiceAccount";
|
String namedQuery = "getRealmUserCountExcludeServiceAccount";
|
||||||
|
@ -602,11 +591,6 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
return ((Number)count).intValue();
|
return ((Number)count).intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getUsersCount(RealmModel realm) {
|
|
||||||
return getUsersCount(realm, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(RealmModel realm, Set<String> groupIds) {
|
public int getUsersCount(RealmModel realm, Set<String> groupIds) {
|
||||||
if (groupIds == null || groupIds.isEmpty()) {
|
if (groupIds == null || groupIds.isEmpty()) {
|
||||||
|
@ -622,7 +606,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(String search, RealmModel realm) {
|
public int getUsersCount(RealmModel realm, String search) {
|
||||||
TypedQuery<Long> query = em.createNamedQuery("searchForUserCount", Long.class);
|
TypedQuery<Long> query = em.createNamedQuery("searchForUserCount", Long.class);
|
||||||
query.setParameter("realmId", realm.getId());
|
query.setParameter("realmId", realm.getId());
|
||||||
query.setParameter("search", "%" + search.toLowerCase() + "%");
|
query.setParameter("search", "%" + search.toLowerCase() + "%");
|
||||||
|
@ -632,7 +616,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(String search, RealmModel realm, Set<String> groupIds) {
|
public int getUsersCount(RealmModel realm, String search, Set<String> groupIds) {
|
||||||
if (groupIds == null || groupIds.isEmpty()) {
|
if (groupIds == null || groupIds.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -647,7 +631,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(Map<String, String> params, RealmModel realm) {
|
public int getUsersCount(RealmModel realm, Map<String, String> params) {
|
||||||
CriteriaBuilder qb = em.getCriteriaBuilder();
|
CriteriaBuilder qb = em.getCriteriaBuilder();
|
||||||
CriteriaQuery<Long> userQuery = qb.createQuery(Long.class);
|
CriteriaQuery<Long> userQuery = qb.createQuery(Long.class);
|
||||||
Root<UserEntity> from = userQuery.from(UserEntity.class);
|
Root<UserEntity> from = userQuery.from(UserEntity.class);
|
||||||
|
@ -691,7 +675,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(Map<String, String> params, RealmModel realm, Set<String> groupIds) {
|
public int getUsersCount(RealmModel realm, Map<String, String> params, Set<String> groupIds) {
|
||||||
if (groupIds == null || groupIds.isEmpty()) {
|
if (groupIds == null || groupIds.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -740,12 +724,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm) {
|
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
return getUsersStream(realm, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
|
|
||||||
return getUsersStream(realm, firstResult, maxResults, false);
|
return getUsersStream(realm, firstResult, maxResults, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -776,25 +755,15 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
||||||
return searchForUserStream(search, realm, -1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
|
|
||||||
Map<String, String> attributes = new HashMap<>();
|
Map<String, String> attributes = new HashMap<>();
|
||||||
attributes.put(UserModel.SEARCH, search);
|
attributes.put(UserModel.SEARCH, search);
|
||||||
session.setAttribute(UserModel.INCLUDE_SERVICE_ACCOUNT, false);
|
session.setAttribute(UserModel.INCLUDE_SERVICE_ACCOUNT, false);
|
||||||
return searchForUserStream(attributes, realm, firstResult, maxResults);
|
return searchForUserStream(realm, attributes, firstResult, maxResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes, Integer firstResult, Integer maxResults) {
|
||||||
return searchForUserStream(attributes, realm, -1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm, Integer firstResult, Integer maxResults) {
|
|
||||||
CriteriaBuilder builder = em.getCriteriaBuilder();
|
CriteriaBuilder builder = em.getCriteriaBuilder();
|
||||||
CriteriaQuery<UserEntity> queryBuilder = builder.createQuery(UserEntity.class);
|
CriteriaQuery<UserEntity> queryBuilder = builder.createQuery(UserEntity.class);
|
||||||
Root<UserEntity> root = queryBuilder.from(UserEntity.class);
|
Root<UserEntity> root = queryBuilder.from(UserEntity.class);
|
||||||
|
@ -903,11 +872,11 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
|
|
||||||
UserProvider users = session.users();
|
UserProvider users = session.users();
|
||||||
return closing(paginateQuery(query, firstResult, maxResults).getResultStream())
|
return closing(paginateQuery(query, firstResult, maxResults).getResultStream())
|
||||||
.map(userEntity -> users.getUserById(userEntity.getId(), realm));
|
.map(userEntity -> users.getUserById(realm, userEntity.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
|
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
|
||||||
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUsersByAttributeNameAndValue", UserEntity.class);
|
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUsersByAttributeNameAndValue", UserEntity.class);
|
||||||
query.setParameter("name", attrName);
|
query.setParameter("name", attrName);
|
||||||
query.setParameter("value", attrValue);
|
query.setParameter("value", attrValue);
|
||||||
|
@ -928,7 +897,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm) {
|
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel realm, UserModel user) {
|
||||||
TypedQuery<FederatedIdentityEntity> query = em.createNamedQuery("findFederatedIdentityByUser", FederatedIdentityEntity.class);
|
TypedQuery<FederatedIdentityEntity> query = em.createNamedQuery("findFederatedIdentityByUser", FederatedIdentityEntity.class);
|
||||||
UserEntity userEntity = em.getReference(UserEntity.class, user.getId());
|
UserEntity userEntity = em.getReference(UserEntity.class, user.getId());
|
||||||
query.setParameter("user", userEntity);
|
query.setParameter("user", userEntity);
|
||||||
|
@ -938,7 +907,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FederatedIdentityModel getFederatedIdentity(UserModel user, String identityProvider, RealmModel realm) {
|
public FederatedIdentityModel getFederatedIdentity(RealmModel realm, UserModel user, String identityProvider) {
|
||||||
FederatedIdentityEntity entity = findFederatedIdentity(user, identityProvider, LockModeType.NONE);
|
FederatedIdentityEntity entity = findFederatedIdentity(user, identityProvider, LockModeType.NONE);
|
||||||
return (entity != null) ? new FederatedIdentityModel(entity.getIdentityProvider(), entity.getUserId(), entity.getUserName(), entity.getToken()) : null;
|
return (entity != null) ? new FederatedIdentityModel(entity.getIdentityProvider(), entity.getUserId(), entity.getUserName(), entity.getToken()) : null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.jpa;
|
||||||
|
|
||||||
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
|
public class PaginationUtils {
|
||||||
|
|
||||||
|
public static final int DEFAULT_MAX_RESULTS = Integer.MAX_VALUE >> 1;
|
||||||
|
|
||||||
|
public static <T> TypedQuery<T> paginateQuery(TypedQuery<T> query, Integer first, Integer max) {
|
||||||
|
if (first != null && first > 0) {
|
||||||
|
query = query.setFirstResult(first);
|
||||||
|
|
||||||
|
// Workaround for https://hibernate.atlassian.net/browse/HHH-14295
|
||||||
|
if (max == null || max < 0) {
|
||||||
|
max = DEFAULT_MAX_RESULTS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max != null && max >= 0) {
|
||||||
|
query = query.setMaxResults(max);
|
||||||
|
}
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -77,7 +77,7 @@ public class MapAuthenticationSessionAdapter implements AuthenticationSessionMod
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getAuthenticatedUser() {
|
public UserModel getAuthenticatedUser() {
|
||||||
return entity.getAuthUserId() == null ? null : session.users().getUserById(entity.getAuthUserId(), getRealm());
|
return entity.getAuthUserId() == null ? null : session.users().getUserById(getRealm(), entity.getAuthUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -38,7 +38,9 @@ import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import org.keycloak.models.map.storage.MapStorage;
|
import org.keycloak.models.map.storage.MapStorage;
|
||||||
|
|
||||||
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
|
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
|
||||||
|
import static org.keycloak.utils.StreamsUtil.paginatedStream;
|
||||||
|
|
||||||
public class MapClientProvider implements ClientProvider {
|
public class MapClientProvider implements ClientProvider {
|
||||||
|
|
||||||
|
@ -130,14 +132,7 @@ public class MapClientProvider implements ClientProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<ClientModel> getClientsStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
public Stream<ClientModel> getClientsStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
Stream<ClientModel> s = getClientsStream(realm);
|
return paginatedStream(getClientsStream(realm), firstResult, maxResults);
|
||||||
if (firstResult != null && firstResult >= 0) {
|
|
||||||
s = s.skip(firstResult);
|
|
||||||
}
|
|
||||||
if (maxResults != null && maxResults >= 0) {
|
|
||||||
s = s.limit(maxResults);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream<MapClientEntity> getNotRemovedUpdatedClientsStream() {
|
private Stream<MapClientEntity> getNotRemovedUpdatedClientsStream() {
|
||||||
|
@ -281,14 +276,7 @@ public class MapClientProvider implements ClientProvider {
|
||||||
.filter(entity -> entity.getClientId() != null && entity.getClientId().toLowerCase().contains(clientIdLower))
|
.filter(entity -> entity.getClientId() != null && entity.getClientId().toLowerCase().contains(clientIdLower))
|
||||||
.sorted(COMPARE_BY_CLIENT_ID);
|
.sorted(COMPARE_BY_CLIENT_ID);
|
||||||
|
|
||||||
if (firstResult != null && firstResult >= 0) {
|
return paginatedStream(s, firstResult, maxResults).map(entityToAdapterFunc(realm));
|
||||||
s = s.skip(firstResult);
|
|
||||||
}
|
|
||||||
if (maxResults != null && maxResults >= 0) {
|
|
||||||
s = s.limit(maxResults);
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.map(entityToAdapterFunc(realm));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -36,6 +36,7 @@ import java.util.function.Predicate;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
|
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
|
||||||
|
import static org.keycloak.utils.StreamsUtil.paginatedStream;
|
||||||
|
|
||||||
public class MapGroupProvider implements GroupProvider {
|
public class MapGroupProvider implements GroupProvider {
|
||||||
|
|
||||||
|
@ -124,15 +125,7 @@ public class MapGroupProvider implements GroupProvider {
|
||||||
groupModelStream = groupModelStream.filter(groupModel -> groupModel.getName().toLowerCase().contains(s));
|
groupModelStream = groupModelStream.filter(groupModel -> groupModel.getName().toLowerCase().contains(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first != null && first > 0) {
|
return paginatedStream(groupModelStream, first, max);
|
||||||
groupModelStream = groupModelStream.skip(first);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max != null && max >= 0) {
|
|
||||||
groupModelStream = groupModelStream.limit(max);
|
|
||||||
}
|
|
||||||
|
|
||||||
return groupModelStream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -157,15 +150,7 @@ public class MapGroupProvider implements GroupProvider {
|
||||||
LOG.tracef("getGroupsByRole(%s, %s, %d, %d)%s", realm, role, firstResult, maxResults, getShortStackTrace());
|
LOG.tracef("getGroupsByRole(%s, %s, %d, %d)%s", realm, role, firstResult, maxResults, getShortStackTrace());
|
||||||
Stream<GroupModel> groupModelStream = getGroupsStream(realm).filter(groupModel -> groupModel.hasRole(role));
|
Stream<GroupModel> groupModelStream = getGroupsStream(realm).filter(groupModel -> groupModel.hasRole(role));
|
||||||
|
|
||||||
if (firstResult != null && firstResult > 0) {
|
return paginatedStream(groupModelStream, firstResult, maxResults);
|
||||||
groupModelStream = groupModelStream.skip(firstResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxResults != null && maxResults >= 0) {
|
|
||||||
groupModelStream = groupModelStream.limit(maxResults);
|
|
||||||
}
|
|
||||||
|
|
||||||
return groupModelStream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -179,15 +164,7 @@ public class MapGroupProvider implements GroupProvider {
|
||||||
public Stream<GroupModel> getTopLevelGroupsStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
public Stream<GroupModel> getTopLevelGroupsStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
Stream<GroupModel> groupModelStream = getTopLevelGroupsStream(realm);
|
Stream<GroupModel> groupModelStream = getTopLevelGroupsStream(realm);
|
||||||
|
|
||||||
if (firstResult != null && firstResult > 0) {
|
return paginatedStream(groupModelStream, firstResult, maxResults);
|
||||||
groupModelStream = groupModelStream.skip(firstResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxResults != null && maxResults >= 0) {
|
|
||||||
groupModelStream = groupModelStream.limit(maxResults);
|
|
||||||
}
|
|
||||||
|
|
||||||
return groupModelStream;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,15 +174,8 @@ public class MapGroupProvider implements GroupProvider {
|
||||||
Stream<GroupModel> groupModelStream = getGroupsStream(realm)
|
Stream<GroupModel> groupModelStream = getGroupsStream(realm)
|
||||||
.filter(groupModel -> groupModel.getName().contains(search));
|
.filter(groupModel -> groupModel.getName().contains(search));
|
||||||
|
|
||||||
if (firstResult != null && firstResult > 0) {
|
|
||||||
groupModelStream = groupModelStream.skip(firstResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxResults != null && maxResults >= 0) {
|
return paginatedStream(groupModelStream, firstResult, maxResults);
|
||||||
groupModelStream = groupModelStream.limit(maxResults);
|
|
||||||
}
|
|
||||||
|
|
||||||
return groupModelStream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -35,6 +35,8 @@ import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import org.keycloak.models.map.storage.MapStorage;
|
import org.keycloak.models.map.storage.MapStorage;
|
||||||
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
|
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
|
||||||
|
import static org.keycloak.utils.StreamsUtil.paginatedStream;
|
||||||
|
|
||||||
import org.keycloak.models.RoleContainerModel;
|
import org.keycloak.models.RoleContainerModel;
|
||||||
import org.keycloak.models.RoleProvider;
|
import org.keycloak.models.RoleProvider;
|
||||||
import org.keycloak.models.map.common.StreamUtils;
|
import org.keycloak.models.map.common.StreamUtils;
|
||||||
|
@ -126,14 +128,7 @@ public class MapRoleProvider implements RoleProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<RoleModel> getRealmRolesStream(RealmModel realm, Integer first, Integer max) {
|
public Stream<RoleModel> getRealmRolesStream(RealmModel realm, Integer first, Integer max) {
|
||||||
Stream<RoleModel> s = getRealmRolesStream(realm);
|
return paginatedStream(getRealmRolesStream(realm), first, max);
|
||||||
if (first != null && first >= 0) {
|
|
||||||
s = s.skip(first);
|
|
||||||
}
|
|
||||||
if (max != null && max >= 0) {
|
|
||||||
s = s.limit(max);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -171,14 +166,7 @@ public class MapRoleProvider implements RoleProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<RoleModel> getClientRolesStream(ClientModel client, Integer first, Integer max) {
|
public Stream<RoleModel> getClientRolesStream(ClientModel client, Integer first, Integer max) {
|
||||||
Stream<RoleModel> s = getClientRolesStream(client);
|
return paginatedStream(getClientRolesStream(client), first, max);
|
||||||
if (first != null && first > 0) {
|
|
||||||
s = s.skip(first);
|
|
||||||
}
|
|
||||||
if (max != null && max >= 0) {
|
|
||||||
s = s.limit(max);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -326,14 +314,7 @@ public class MapRoleProvider implements RoleProvider {
|
||||||
)
|
)
|
||||||
.sorted(COMPARE_BY_NAME);
|
.sorted(COMPARE_BY_NAME);
|
||||||
|
|
||||||
if (first != null && first > 0) {
|
return paginatedStream(s.map(entityToAdapterFunc(realm)), first, max);
|
||||||
s = s.skip(first);
|
|
||||||
}
|
|
||||||
if (max != null && max >= 0) {
|
|
||||||
s = s.limit(max);
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.map(entityToAdapterFunc(realm));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -350,14 +331,7 @@ public class MapRoleProvider implements RoleProvider {
|
||||||
)
|
)
|
||||||
.sorted(COMPARE_BY_NAME);
|
.sorted(COMPARE_BY_NAME);
|
||||||
|
|
||||||
if (first != null && first > 0) {
|
return paginatedStream(s,first, max).map(entityToAdapterFunc(client.getRealm()));
|
||||||
s = s.skip(first);
|
|
||||||
}
|
|
||||||
if (max != null && max >= 0) {
|
|
||||||
s = s.limit(max);
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.map(entityToAdapterFunc(client.getRealm()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -68,6 +68,7 @@ import static org.keycloak.models.UserModel.EMAIL_VERIFIED;
|
||||||
import static org.keycloak.models.UserModel.FIRST_NAME;
|
import static org.keycloak.models.UserModel.FIRST_NAME;
|
||||||
import static org.keycloak.models.UserModel.LAST_NAME;
|
import static org.keycloak.models.UserModel.LAST_NAME;
|
||||||
import static org.keycloak.models.UserModel.USERNAME;
|
import static org.keycloak.models.UserModel.USERNAME;
|
||||||
|
import static org.keycloak.utils.StreamsUtil.paginatedStream;
|
||||||
|
|
||||||
public class MapUserProvider implements UserProvider.Streams, UserCredentialStore.Streams {
|
public class MapUserProvider implements UserProvider.Streams, UserCredentialStore.Streams {
|
||||||
|
|
||||||
|
@ -96,12 +97,12 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkEmailUniqueness(RealmModel realm, String email) {
|
public boolean checkEmailUniqueness(RealmModel realm, String email) {
|
||||||
return getUserByEmail(email, realm) != null;
|
return getUserByEmail(realm, email) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkUsernameUniqueness(RealmModel realm, String username) {
|
public boolean checkUsernameUniqueness(RealmModel realm, String username) {
|
||||||
return getUserByUsername(username, realm) != null;
|
return getUserByUsername(realm, username) != null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -157,18 +158,6 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
.filter(entityRealmFilter(realm));
|
.filter(entityRealmFilter(realm));
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> Stream<T> paginatedStream(Stream<T> originalStream, Integer first, Integer max) {
|
|
||||||
if (first != null && first > 0) {
|
|
||||||
originalStream = originalStream.skip(first);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max != null && max >= 0) {
|
|
||||||
originalStream = originalStream.limit(max);
|
|
||||||
}
|
|
||||||
|
|
||||||
return originalStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink) {
|
public void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink) {
|
||||||
if (user == null || user.getId() == null) {
|
if (user == null || user.getId() == null) {
|
||||||
|
@ -206,7 +195,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm) {
|
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel realm, UserModel user) {
|
||||||
LOG.tracef("getFederatedIdentitiesStream(%s, %s)%s", realm, user.getId(), getShortStackTrace());
|
LOG.tracef("getFederatedIdentitiesStream(%s, %s)%s", realm, user.getId(), getShortStackTrace());
|
||||||
return getEntityById(realm, user.getId())
|
return getEntityById(realm, user.getId())
|
||||||
.map(AbstractUserEntity::getFederatedIdentities).orElseGet(Stream::empty)
|
.map(AbstractUserEntity::getFederatedIdentities).orElseGet(Stream::empty)
|
||||||
|
@ -214,7 +203,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm) {
|
public FederatedIdentityModel getFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
|
||||||
LOG.tracef("getFederatedIdentity(%s, %s, %s)%s", realm, user.getId(), socialProvider, getShortStackTrace());
|
LOG.tracef("getFederatedIdentity(%s, %s, %s)%s", realm, user.getId(), socialProvider, getShortStackTrace());
|
||||||
return getEntityById(realm, user.getId())
|
return getEntityById(realm, user.getId())
|
||||||
.map(userEntity -> userEntity.getFederatedIdentity(socialProvider))
|
.map(userEntity -> userEntity.getFederatedIdentity(socialProvider))
|
||||||
|
@ -223,7 +212,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm) {
|
public UserModel getUserByFederatedIdentity(RealmModel realm, FederatedIdentityModel socialLink) {
|
||||||
LOG.tracef("getUserByFederatedIdentity(%s, %s)%s", realm, socialLink, getShortStackTrace());
|
LOG.tracef("getUserByFederatedIdentity(%s, %s)%s", realm, socialLink, getShortStackTrace());
|
||||||
return getUnsortedUserEntitiesStream(realm)
|
return getUnsortedUserEntitiesStream(realm)
|
||||||
.filter(userEntity -> Objects.nonNull(userEntity.getFederatedIdentity(socialLink.getIdentityProvider())))
|
.filter(userEntity -> Objects.nonNull(userEntity.getFederatedIdentity(socialLink.getIdentityProvider())))
|
||||||
|
@ -231,7 +220,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
.collect(Collectors.collectingAndThen(
|
.collect(Collectors.collectingAndThen(
|
||||||
Collectors.toList(),
|
Collectors.toList(),
|
||||||
list -> {
|
list -> {
|
||||||
if (list.size() == 0) {
|
if (list.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
} else if (list.size() != 1) {
|
} else if (list.size() != 1) {
|
||||||
throw new IllegalStateException("More results found for identityProvider=" + socialLink.getIdentityProvider() +
|
throw new IllegalStateException("More results found for identityProvider=" + socialLink.getIdentityProvider() +
|
||||||
|
@ -246,8 +235,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
public void addConsent(RealmModel realm, String userId, UserConsentModel consent) {
|
public void addConsent(RealmModel realm, String userId, UserConsentModel consent) {
|
||||||
LOG.tracef("addConsent(%s, %s, %s)%s", realm, userId, consent, getShortStackTrace());
|
LOG.tracef("addConsent(%s, %s, %s)%s", realm, userId, consent, getShortStackTrace());
|
||||||
|
|
||||||
UserConsentEntity consentEntity = UserConsentEntity.fromModel(consent);
|
getRegisteredEntityByIdOrThrow(realm, userId)
|
||||||
getRegisteredEntityById(realm, userId).ifPresent(userEntity -> userEntity.addUserConsent(consentEntity));
|
.addUserConsent(UserConsentEntity.fromModel(consent));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -298,15 +287,15 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
@Override
|
@Override
|
||||||
public void setNotBeforeForUser(RealmModel realm, UserModel user, int notBefore) {
|
public void setNotBeforeForUser(RealmModel realm, UserModel user, int notBefore) {
|
||||||
LOG.tracef("setNotBeforeForUser(%s, %s, %d)%s", realm, user.getId(), notBefore, getShortStackTrace());
|
LOG.tracef("setNotBeforeForUser(%s, %s, %d)%s", realm, user.getId(), notBefore, getShortStackTrace());
|
||||||
getRegisteredEntityById(realm, user.getId()).ifPresent(userEntity -> userEntity.setNotBefore(notBefore));
|
getRegisteredEntityByIdOrThrow(realm, user.getId()).setNotBefore(notBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNotBeforeOfUser(RealmModel realm, UserModel user) {
|
public int getNotBeforeOfUser(RealmModel realm, UserModel user) {
|
||||||
LOG.tracef("getNotBeforeOfUser(%s, %s)%s", realm, user.getId(), getShortStackTrace());
|
LOG.tracef("getNotBeforeOfUser(%s, %s)%s", realm, user.getId(), getShortStackTrace());
|
||||||
return getEntityById(realm, user.getId())
|
return getEntityById(realm, user.getId())
|
||||||
.map(AbstractUserEntity::getNotBefore)
|
.orElseThrow(this::userDoesntExistException)
|
||||||
.orElse(0);
|
.getNotBefore();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -317,7 +306,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
.collect(Collectors.collectingAndThen(
|
.collect(Collectors.collectingAndThen(
|
||||||
Collectors.toList(),
|
Collectors.toList(),
|
||||||
list -> {
|
list -> {
|
||||||
if (list.size() == 0) {
|
if (list.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
} else if (list.size() != 1) {
|
} else if (list.size() != 1) {
|
||||||
throw new IllegalStateException("More service account linked users found for client=" + client.getClientId() +
|
throw new IllegalStateException("More service account linked users found for client=" + client.getClientId() +
|
||||||
|
@ -479,13 +468,13 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
public UserModel getUserById(RealmModel realm, String id) {
|
||||||
LOG.tracef("getUserById(%s, %s)%s", realm, id, getShortStackTrace());
|
LOG.tracef("getUserById(%s, %s)%s", realm, id, getShortStackTrace());
|
||||||
return getEntityById(realm, id).map(entityToAdapterFunc(realm)).orElse(null);
|
return getEntityById(realm, id).map(entityToAdapterFunc(realm)).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
public UserModel getUserByUsername(RealmModel realm, String username) {
|
||||||
if (username == null) return null;
|
if (username == null) return null;
|
||||||
final String usernameLowercase = username.toLowerCase();
|
final String usernameLowercase = username.toLowerCase();
|
||||||
|
|
||||||
|
@ -497,12 +486,12 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
public UserModel getUserByEmail(RealmModel realm, String email) {
|
||||||
LOG.tracef("getUserByEmail(%s, %s)%s", realm, email, getShortStackTrace());
|
LOG.tracef("getUserByEmail(%s, %s)%s", realm, email, getShortStackTrace());
|
||||||
List<MapUserEntity> usersWithEmail = getUnsortedUserEntitiesStream(realm)
|
List<MapUserEntity> usersWithEmail = getUnsortedUserEntitiesStream(realm)
|
||||||
.filter(userEntity -> Objects.equals(userEntity.getEmail(), email))
|
.filter(userEntity -> Objects.equals(userEntity.getEmail(), email.toLowerCase()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (usersWithEmail.size() == 0) return null;
|
if (usersWithEmail.isEmpty()) return null;
|
||||||
|
|
||||||
if (usersWithEmail.size() > 1) {
|
if (usersWithEmail.size() > 1) {
|
||||||
// Realm settings have been changed from allowing duplicate emails to not allowing them
|
// Realm settings have been changed from allowing duplicate emails to not allowing them
|
||||||
|
@ -523,21 +512,15 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
return new MapUserAdapter(session, realm, userEntity) {
|
return new MapUserAdapter(session, realm, userEntity) {
|
||||||
@Override
|
@Override
|
||||||
public boolean checkEmailUniqueness(RealmModel realm, String email) {
|
public boolean checkEmailUniqueness(RealmModel realm, String email) {
|
||||||
return getUserByEmail(email, realm) != null;
|
return getUserByEmail(realm, email) != null;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean checkUsernameUniqueness(RealmModel realm, String username) {
|
public boolean checkUsernameUniqueness(RealmModel realm, String username) {
|
||||||
return getUserByUsername(username, realm) != null;
|
return getUserByUsername(realm, username) != null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getUsersCount(RealmModel realm) {
|
|
||||||
LOG.tracef("getUsersCount(%s)%s", realm, getShortStackTrace());
|
|
||||||
return getUsersCount(realm, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(RealmModel realm, boolean includeServiceAccount) {
|
public int getUsersCount(RealmModel realm, boolean includeServiceAccount) {
|
||||||
LOG.tracef("getUsersCount(%s, %s)%s", realm, includeServiceAccount, getShortStackTrace());
|
LOG.tracef("getUsersCount(%s, %s)%s", realm, includeServiceAccount, getShortStackTrace());
|
||||||
|
@ -564,46 +547,22 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm) {
|
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
LOG.tracef("getUsersStream(%s)%s", realm, getShortStackTrace());
|
|
||||||
return getUsersStream(realm, null, null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts) {
|
|
||||||
LOG.tracef("getUsersStream(%s)%s", realm, getShortStackTrace());
|
|
||||||
return getUsersStream(realm, null, null, includeServiceAccounts);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
|
|
||||||
LOG.tracef("getUsersStream(%s, %d, %d)%s", realm, firstResult, maxResults, getShortStackTrace());
|
LOG.tracef("getUsersStream(%s, %d, %d)%s", realm, firstResult, maxResults, getShortStackTrace());
|
||||||
return getUsersStream(realm, firstResult, maxResults, false);
|
return getUsersStream(realm, firstResult, maxResults, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
||||||
LOG.tracef("searchForUserStream(%s, %s)%s", realm, search, getShortStackTrace());
|
|
||||||
return searchForUserStream(search, realm, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
|
|
||||||
LOG.tracef("searchForUserStream(%s, %s, %d, %d)%s", realm, search, firstResult, maxResults, getShortStackTrace());
|
LOG.tracef("searchForUserStream(%s, %s, %d, %d)%s", realm, search, firstResult, maxResults, getShortStackTrace());
|
||||||
Map<String, String> attributes = new HashMap<>();
|
Map<String, String> attributes = new HashMap<>();
|
||||||
attributes.put(UserModel.SEARCH, search);
|
attributes.put(UserModel.SEARCH, search);
|
||||||
session.setAttribute(UserModel.INCLUDE_SERVICE_ACCOUNT, false);
|
session.setAttribute(UserModel.INCLUDE_SERVICE_ACCOUNT, false);
|
||||||
return searchForUserStream(attributes, realm, firstResult, maxResults);
|
return searchForUserStream(realm, attributes, firstResult, maxResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes, Integer firstResult, Integer maxResults) {
|
||||||
LOG.tracef("searchForUserStream(%s, %s)%s", realm, params, getShortStackTrace());
|
|
||||||
return searchForUserStream(params, realm, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm, Integer firstResult, Integer maxResults) {
|
|
||||||
LOG.tracef("searchForUserStream(%s, %s, %d, %d)%s", realm, attributes, firstResult, maxResults, getShortStackTrace());
|
LOG.tracef("searchForUserStream(%s, %s, %d, %d)%s", realm, attributes, firstResult, maxResults, getShortStackTrace());
|
||||||
/* Find all predicates based on attributes map */
|
/* Find all predicates based on attributes map */
|
||||||
List<Predicate<MapUserEntity>> predicatesList = new ArrayList<>();
|
List<Predicate<MapUserEntity>> predicatesList = new ArrayList<>();
|
||||||
|
@ -735,13 +694,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
|
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
|
||||||
LOG.tracef("getGroupMembersStream(%s, %s)%s", realm, group.getId(), getShortStackTrace());
|
|
||||||
return getGroupMembersStream(realm, group, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
|
|
||||||
LOG.tracef("searchForUserByUserAttributeStream(%s, %s, %s)%s", realm, attrName, attrValue, getShortStackTrace());
|
LOG.tracef("searchForUserByUserAttributeStream(%s, %s, %s)%s", realm, attrName, attrValue, getShortStackTrace());
|
||||||
return getUnsortedUserEntitiesStream(realm)
|
return getUnsortedUserEntitiesStream(realm)
|
||||||
.filter(userEntity -> userEntity.getAttribute(attrName).contains(attrValue))
|
.filter(userEntity -> userEntity.getAttribute(attrName).contains(attrValue))
|
||||||
|
|
|
@ -61,7 +61,6 @@ import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserProvider;
|
import org.keycloak.models.UserProvider;
|
||||||
import org.keycloak.models.dblock.DBLockManager;
|
import org.keycloak.models.dblock.DBLockManager;
|
||||||
import org.keycloak.models.dblock.DBLockProvider;
|
import org.keycloak.models.dblock.DBLockProvider;
|
||||||
import org.keycloak.models.utils.DefaultKeyProviders;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.models.utils.RepresentationToModel;
|
import org.keycloak.models.utils.RepresentationToModel;
|
||||||
import org.keycloak.provider.ServerInfoAwareProviderFactory;
|
import org.keycloak.provider.ServerInfoAwareProviderFactory;
|
||||||
|
@ -497,7 +496,7 @@ public class QuarkusJpaConnectionProviderFactory implements JpaConnectionProvide
|
||||||
|
|
||||||
UserProvider users = session.users();
|
UserProvider users = session.users();
|
||||||
|
|
||||||
if (users.getUserByUsername(userRep.getUsername(), realm) != null) {
|
if (users.getUserByUsername(realm, userRep.getUsername()) != null) {
|
||||||
ServicesLogger.LOGGER.notCreatingExistingUser(userRep.getUsername());
|
ServicesLogger.LOGGER.notCreatingExistingUser(userRep.getUsername());
|
||||||
} else {
|
} else {
|
||||||
UserModel user = users.addUser(realm, userRep.getUsername());
|
UserModel user = users.addUser(realm, userRep.getUsername());
|
||||||
|
|
|
@ -165,13 +165,13 @@ public class DefaultEvaluation implements Evaluation {
|
||||||
|
|
||||||
private UserModel getUser(String id, KeycloakSession session) {
|
private UserModel getUser(String id, KeycloakSession session) {
|
||||||
RealmModel realm = session.getContext().getRealm();
|
RealmModel realm = session.getContext().getRealm();
|
||||||
UserModel user = session.users().getUserById(id, realm);
|
UserModel user = session.users().getUserById(realm, id);
|
||||||
|
|
||||||
if (Objects.isNull(user)) {
|
if (Objects.isNull(user)) {
|
||||||
user = session.users().getUserByUsername(id, realm);
|
user = session.users().getUserByUsername(realm ,id);
|
||||||
}
|
}
|
||||||
if (Objects.isNull(user)) {
|
if (Objects.isNull(user)) {
|
||||||
user = session.users().getUserByEmail(id, realm);
|
user = session.users().getUserByEmail(realm, id);
|
||||||
}
|
}
|
||||||
if (Objects.isNull(user)) {
|
if (Objects.isNull(user)) {
|
||||||
user = session.users().getServiceAccount(realm.getClientById(id));
|
user = session.users().getServiceAccount(realm.getClientById(id));
|
||||||
|
|
|
@ -120,7 +120,7 @@ public class PersistentUserSessionAdapter implements OfflineUserSessionModel {
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUser() {
|
public UserModel getUser() {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
user = session.users().getUserById(userId, realm);
|
user = session.users().getUserById(realm, userId);
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,13 +205,13 @@ public final class KeycloakModelUtils {
|
||||||
*/
|
*/
|
||||||
public static UserModel findUserByNameOrEmail(KeycloakSession session, RealmModel realm, String username) {
|
public static UserModel findUserByNameOrEmail(KeycloakSession session, RealmModel realm, String username) {
|
||||||
if (realm.isLoginWithEmailAllowed() && username.indexOf('@') != -1) {
|
if (realm.isLoginWithEmailAllowed() && username.indexOf('@') != -1) {
|
||||||
UserModel user = session.users().getUserByEmail(username, realm);
|
UserModel user = session.users().getUserByEmail(realm, username);
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return session.users().getUserByUsername(username, realm);
|
return session.users().getUserByUsername(realm, username);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -885,7 +885,7 @@ public class ModelToRepresentation {
|
||||||
ClientModel clientModel = realm.getClientById(resourceServer);
|
ClientModel clientModel = realm.getClientById(resourceServer);
|
||||||
owner.setName(clientModel.getClientId());
|
owner.setName(clientModel.getClientId());
|
||||||
} else {
|
} else {
|
||||||
UserModel userModel = keycloakSession.users().getUserById(owner.getId(), realm);
|
UserModel userModel = keycloakSession.users().getUserById(realm, owner.getId());
|
||||||
|
|
||||||
if (userModel == null) {
|
if (userModel == null) {
|
||||||
throw new RuntimeException("Could not find the user [" + owner.getId() + "] who owns the Resource [" + resource.getId() + "].");
|
throw new RuntimeException("Could not find the user [" + owner.getId() + "] who owns the Resource [" + resource.getId() + "].");
|
||||||
|
@ -934,8 +934,8 @@ public class ModelToRepresentation {
|
||||||
representation.setResourceName(resource.getName());
|
representation.setResourceName(resource.getName());
|
||||||
KeycloakSession keycloakSession = authorization.getKeycloakSession();
|
KeycloakSession keycloakSession = authorization.getKeycloakSession();
|
||||||
RealmModel realm = authorization.getRealm();
|
RealmModel realm = authorization.getRealm();
|
||||||
UserModel userOwner = keycloakSession.users().getUserById(ticket.getOwner(), realm);
|
UserModel userOwner = keycloakSession.users().getUserById(realm, ticket.getOwner());
|
||||||
UserModel requester = keycloakSession.users().getUserById(ticket.getRequester(), realm);
|
UserModel requester = keycloakSession.users().getUserById(realm, ticket.getRequester());
|
||||||
representation.setRequesterName(requester.getUsername());
|
representation.setRequesterName(requester.getUsername());
|
||||||
if (userOwner != null) {
|
if (userOwner != null) {
|
||||||
representation.setOwnerName(userOwner.getUsername());
|
representation.setOwnerName(userOwner.getUsername());
|
||||||
|
|
|
@ -2257,7 +2257,7 @@ public class RepresentationToModel {
|
||||||
owner.setId(resourceServer.getId());
|
owner.setId(resourceServer.getId());
|
||||||
resource.setOwner(owner);
|
resource.setOwner(owner);
|
||||||
} else if (owner.getName() != null) {
|
} else if (owner.getName() != null) {
|
||||||
UserModel user = session.users().getUserByUsername(owner.getName(), realm);
|
UserModel user = session.users().getUserByUsername(realm, owner.getName());
|
||||||
|
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
owner.setId(user.getId());
|
owner.setId(user.getId());
|
||||||
|
@ -2572,10 +2572,10 @@ public class RepresentationToModel {
|
||||||
RealmModel realm = authorization.getRealm();
|
RealmModel realm = authorization.getRealm();
|
||||||
KeycloakSession keycloakSession = authorization.getKeycloakSession();
|
KeycloakSession keycloakSession = authorization.getKeycloakSession();
|
||||||
UserProvider users = keycloakSession.users();
|
UserProvider users = keycloakSession.users();
|
||||||
UserModel ownerModel = users.getUserById(ownerId, realm);
|
UserModel ownerModel = users.getUserById(realm, ownerId);
|
||||||
|
|
||||||
if (ownerModel == null) {
|
if (ownerModel == null) {
|
||||||
ownerModel = users.getUserByUsername(ownerId, realm);
|
ownerModel = users.getUserByUsername(realm, ownerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ownerModel == null) {
|
if (ownerModel == null) {
|
||||||
|
|
|
@ -24,6 +24,15 @@ import java.util.stream.Stream;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
public class StreamsUtil {
|
public class StreamsUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the original stream that is closed on terminating operation.
|
||||||
|
*
|
||||||
|
* It is used, for example, for closing hibernate provided streams since it is required by hibernate documentation.
|
||||||
|
*
|
||||||
|
* @param stream the stream which is expected to be closed on termination
|
||||||
|
* @return stream that will be closed on terminating operation
|
||||||
|
*/
|
||||||
public static <T> Stream<T> closing(Stream<T> stream) {
|
public static <T> Stream<T> closing(Stream<T> stream) {
|
||||||
return Stream.of(stream).flatMap(Function.identity());
|
return Stream.of(stream).flatMap(Function.identity());
|
||||||
}
|
}
|
||||||
|
@ -42,4 +51,26 @@ public class StreamsUtil {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the original stream that is limited with {@link Stream#skip(long) skip} and
|
||||||
|
* {@link Stream#limit(long) limit} functions based on values of {@code first} and {@code max} parameters.
|
||||||
|
*
|
||||||
|
* @param originalStream Stream to be limited.
|
||||||
|
* @param first Index of first item to be returned by the stream. Ignored if negative, zero {@code null}.
|
||||||
|
* @param max Maximum number of items to be returned by the stream. Ignored if negative or {@code null}.
|
||||||
|
* @param <T> Type of items in the stream
|
||||||
|
* @return Stream
|
||||||
|
*/
|
||||||
|
public static <T> Stream<T> paginatedStream(Stream<T> originalStream, Integer first, Integer max) {
|
||||||
|
if (first != null && first > 0) {
|
||||||
|
originalStream = originalStream.skip(first);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max != null && max >= 0) {
|
||||||
|
originalStream = originalStream.limit(max);
|
||||||
|
}
|
||||||
|
|
||||||
|
return originalStream;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
|
||||||
* @param id Id.
|
* @param id Id.
|
||||||
* @param realm Realm.
|
* @param realm Realm.
|
||||||
* @return GroupModel with the corresponding id.
|
* @return GroupModel with the corresponding id.
|
||||||
* @deprecated Use method {@code getGroupById(realm, id)}
|
* @deprecated Use method {@link #getGroupById(RealmModel, String) getGroupById}
|
||||||
*/
|
*/
|
||||||
default GroupModel getGroupById(String id, RealmModel realm) {
|
default GroupModel getGroupById(String id, RealmModel realm) {
|
||||||
return getGroupById(realm, id);
|
return getGroupById(realm, id);
|
||||||
|
@ -140,7 +140,7 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
|
||||||
* @param firstResult First result to return. Ignored if negative.
|
* @param firstResult First result to return. Ignored if negative.
|
||||||
* @param maxResults Maximum number of results to return. Ignored if negative.
|
* @param maxResults Maximum number of results to return. Ignored if negative.
|
||||||
* @return List of groups with the given role.
|
* @return List of groups with the given role.
|
||||||
* @deprecated Use {@link #getGroupsByRoleStream(RealmModel, RoleModel, int, int) getGroupsByRoleStream} instead.
|
* @deprecated Use {@link #getGroupsByRoleStream(RealmModel, RoleModel, Integer, Integer) getGroupsByRoleStream} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
default List<GroupModel> getGroupsByRole(RealmModel realm, RoleModel role, int firstResult, int maxResults) {
|
default List<GroupModel> getGroupsByRole(RealmModel realm, RoleModel role, int firstResult, int maxResults) {
|
||||||
|
|
|
@ -38,73 +38,35 @@ public interface UserProvider extends Provider,
|
||||||
UserQueryProvider,
|
UserQueryProvider,
|
||||||
UserRegistrationProvider,
|
UserRegistrationProvider,
|
||||||
UserBulkUpdateProvider {
|
UserBulkUpdateProvider {
|
||||||
// Note: The reason there are so many query methods here is for layering a cache on top of an persistent KeycloakSession
|
|
||||||
|
|
||||||
void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink);
|
|
||||||
boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider);
|
|
||||||
void preRemove(RealmModel realm, IdentityProviderModel provider);
|
|
||||||
void updateFederatedIdentity(RealmModel realm, UserModel federatedUser, FederatedIdentityModel federatedIdentityModel);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link #getFederatedIdentitiesStream(UserModel, RealmModel) getFederatedIdentitiesStream} instead.
|
* Sets the notBefore value for the given user
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtains the federated identities of the specified user.
|
|
||||||
*
|
*
|
||||||
* @param user a reference to the user.
|
* @param realm a reference to the realm
|
||||||
* @param realm a reference to the realm.
|
* @param user the user model
|
||||||
* @return a non-null {@link Stream} of federated identities associated with the user.
|
* @param notBefore new value for notBefore
|
||||||
*/
|
|
||||||
default Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm) {
|
|
||||||
Set<FederatedIdentityModel> value = this.getFederatedIdentities(user, realm);
|
|
||||||
return value != null ? value.stream() : Stream.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm);
|
|
||||||
UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm);
|
|
||||||
|
|
||||||
void addConsent(RealmModel realm, String userId, UserConsentModel consent);
|
|
||||||
UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientInternalId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use {@link #getConsentsStream(RealmModel, String) getConsentsStream} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
List<UserConsentModel> getConsents(RealmModel realm, String userId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtains the consents associated with the user identified by the specified {@code userId}.
|
|
||||||
*
|
*
|
||||||
* @param realm a reference to the realm.
|
* @throws ModelException when user doesn't exist in the storage
|
||||||
* @param userId the user identifier.
|
|
||||||
* @return a non-null {@link Stream} of consents associated with the user.
|
|
||||||
*/
|
*/
|
||||||
default Stream<UserConsentModel> getConsentsStream(RealmModel realm, String userId) {
|
|
||||||
List<UserConsentModel> value = this.getConsents(realm, userId);
|
|
||||||
return value != null ? value.stream() : Stream.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param realm
|
|
||||||
* @param userId
|
|
||||||
* @param consent
|
|
||||||
* @throws ModelException when consent doesn't exist for the userId
|
|
||||||
*/
|
|
||||||
void updateConsent(RealmModel realm, String userId, UserConsentModel consent);
|
|
||||||
boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId);
|
|
||||||
|
|
||||||
void setNotBeforeForUser(RealmModel realm, UserModel user, int notBefore);
|
void setNotBeforeForUser(RealmModel realm, UserModel user, int notBefore);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the notBefore value for the given user
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param user the user model
|
||||||
|
* @return the value of notBefore
|
||||||
|
*
|
||||||
|
* @throws ModelException when user doesn't exist in the storage
|
||||||
|
*/
|
||||||
int getNotBeforeOfUser(RealmModel realm, UserModel user);
|
int getNotBeforeOfUser(RealmModel realm, UserModel user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Return a UserModel representing service account of the client
|
||||||
*
|
*
|
||||||
* @param client
|
* @param client the client model
|
||||||
* @throws IllegalArgumentException when there are more service accounts associated with the given clientId
|
* @throws IllegalArgumentException when there are more service accounts associated with the given clientId
|
||||||
* @return
|
* @return userModel representing service account of the client
|
||||||
*/
|
*/
|
||||||
UserModel getServiceAccount(ClientModel client);
|
UserModel getServiceAccount(ClientModel client);
|
||||||
|
|
||||||
|
@ -136,8 +98,8 @@ public interface UserProvider extends Provider,
|
||||||
* Obtains the users associated with the specified realm.
|
* Obtains the users associated with the specified realm.
|
||||||
*
|
*
|
||||||
* @param realm a reference to the realm being used for the search.
|
* @param realm a reference to the realm being used for the search.
|
||||||
* @param firstResult first result to return. Ignored if negative.
|
* @param firstResult first result to return. Ignored if negative, zero, or {@code null}.
|
||||||
* @param maxResults maximum number of results to return. Ignored if negative.
|
* @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
|
||||||
* @param includeServiceAccounts {@code true} if service accounts should be included in the result; {@code false} otherwise.
|
* @param includeServiceAccounts {@code true} if service accounts should be included in the result; {@code false} otherwise.
|
||||||
* @return a non-null {@link Stream} of users associated withe the realm.
|
* @return a non-null {@link Stream} of users associated withe the realm.
|
||||||
*/
|
*/
|
||||||
|
@ -147,53 +109,297 @@ public interface UserProvider extends Provider,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Adds a new user into the storage.
|
||||||
|
* <p/>
|
||||||
* only used for local storage
|
* only used for local storage
|
||||||
*
|
*
|
||||||
* @param realm
|
* @param realm the realm that user will be created in
|
||||||
* @param id
|
* @param id id of the new user. Should be generated to a random value if {@code null}.
|
||||||
* @param username
|
* @param username username
|
||||||
* @param addDefaultRoles
|
* @param addDefaultRoles if {@code true}, the user should join all realm default roles
|
||||||
* @param addDefaultRequiredActions
|
* @param addDefaultRequiredActions if {@code true}, all default required actions are added to the created user
|
||||||
* @return
|
* @return model of created user
|
||||||
|
*
|
||||||
|
* @throws NullPointerException when username or realm is {@code null}
|
||||||
|
* @throws ModelDuplicateException when a user with given id or username already exists
|
||||||
*/
|
*/
|
||||||
UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions);
|
UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions);
|
||||||
void preRemove(RealmModel realm);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes any imported users from a specific User Storage Provider.
|
* Removes any imported users from a specific User Storage Provider.
|
||||||
*
|
*
|
||||||
* @param realm
|
* @param realm a reference to the realm
|
||||||
* @param storageProviderId
|
* @param storageProviderId id of the user storage provider
|
||||||
*/
|
*/
|
||||||
void removeImportedUsers(RealmModel realm, String storageProviderId);
|
void removeImportedUsers(RealmModel realm, String storageProviderId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set federation link to null to imported users of a specific User Storage Provider
|
* Set federation link to {@code null} to imported users of a specific User Storage Provider
|
||||||
*
|
*
|
||||||
* @param realm
|
* @param realm a reference to the realm
|
||||||
* @param storageProviderId
|
* @param storageProviderId id of the storage provider
|
||||||
*/
|
*/
|
||||||
void unlinkUsers(RealmModel realm, String storageProviderId);
|
void unlinkUsers(RealmModel realm, String storageProviderId);
|
||||||
|
|
||||||
|
/* USER CONSENTS methods */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add user consent for the user.
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param userId id of the user
|
||||||
|
* @param consent all details corresponding to the granted consent
|
||||||
|
*
|
||||||
|
* @throws ModelException If there is no user with userId
|
||||||
|
*/
|
||||||
|
void addConsent(RealmModel realm, String userId, UserConsentModel consent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns UserConsentModel given by a user with the userId for the client with clientInternalId
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param userId id of the user
|
||||||
|
* @param clientInternalId id of the client
|
||||||
|
* @return consent given by the user to the client or {@code null} if no consent or user exists
|
||||||
|
*
|
||||||
|
* @throws ModelException when there are more consents fulfilling specified parameters
|
||||||
|
*/
|
||||||
|
UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientInternalId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getConsentsStream(RealmModel, String) getConsentsStream} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
List<UserConsentModel> getConsents(RealmModel realm, String userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains the consents associated with the user identified by the specified {@code userId}.
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm.
|
||||||
|
* @param userId the user identifier.
|
||||||
|
* @return a non-null {@link Stream} of consents associated with the user.
|
||||||
|
*/
|
||||||
|
default Stream<UserConsentModel> getConsentsStream(RealmModel realm, String userId) {
|
||||||
|
List<UserConsentModel> value = this.getConsents(realm, userId);
|
||||||
|
return value != null ? value.stream() : Stream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update client scopes in the stored user consent
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param userId id of the user
|
||||||
|
* @param consent new details of the user consent
|
||||||
|
*
|
||||||
|
* @throws ModelException when consent doesn't exist for the userId
|
||||||
|
*/
|
||||||
|
void updateConsent(RealmModel realm, String userId, UserConsentModel consent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a user consent given by the user id and client id
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param userId id of the user
|
||||||
|
* @param clientInternalId id of the client
|
||||||
|
* @return {@code true} if the consent was removed, {@code false} otherwise
|
||||||
|
*/
|
||||||
|
boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId);
|
||||||
|
|
||||||
|
/* FEDERATED IDENTITIES methods */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a federated identity link for the user within the realm
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param user the user model
|
||||||
|
* @param socialLink the federated identity model containing all details of the association between the user and
|
||||||
|
* the identity provider
|
||||||
|
*/
|
||||||
|
void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes federation link between the user and the identity provider given by its id
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param user the user model
|
||||||
|
* @param socialProvider alias of the identity provider, see {@link IdentityProviderModel#getAlias()}
|
||||||
|
* @return {@code true} if the association was removed, {@code false} otherwise
|
||||||
|
*/
|
||||||
|
boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update details of association between the federatedUser and the idp given by the federatedIdentityModel
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param federatedUser the user model
|
||||||
|
* @param federatedIdentityModel the federated identity model containing all details of the association between
|
||||||
|
* the user and the identity provider
|
||||||
|
*/
|
||||||
|
void updateFederatedIdentity(RealmModel realm, UserModel federatedUser, FederatedIdentityModel federatedIdentityModel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getFederatedIdentitiesStream(RealmModel, UserModel) getFederatedIdentitiesStream} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains the federated identities of the specified user.
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm.
|
||||||
|
* @param user the reference to the user.
|
||||||
|
* @return a non-null {@link Stream} of federated identities associated with the user.
|
||||||
|
*/
|
||||||
|
default Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel realm, UserModel user) {
|
||||||
|
Set<FederatedIdentityModel> value = this.getFederatedIdentities(user, realm);
|
||||||
|
return value != null ? value.stream() : Stream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns details of the association between the user and the socialProvider.
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param user the user model
|
||||||
|
* @param socialProvider the id of the identity provider
|
||||||
|
* @return federatedIdentityModel or {@code null} if no association exists
|
||||||
|
*/
|
||||||
|
default FederatedIdentityModel getFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
|
||||||
|
return getFederatedIdentity(user, socialProvider, realm);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getFederatedIdentity(RealmModel, UserModel, String) getFederatedIdentity} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a userModel that corresponds to the given socialLink.
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param socialLink the socialLink
|
||||||
|
* @return the user corresponding to socialLink and {@code null} if no such user exists
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException when there are more users for the given socialLink
|
||||||
|
*/
|
||||||
|
default UserModel getUserByFederatedIdentity(RealmModel realm, FederatedIdentityModel socialLink) {
|
||||||
|
return getUserByFederatedIdentity(socialLink, realm);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getUserByFederatedIdentity(RealmModel, FederatedIdentityModel) getUserByFederatedIdentity} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm);
|
||||||
|
|
||||||
|
/* PRE REMOVE methods - for cleaning user related properties when some other entity is removed */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a realm is removed.
|
||||||
|
* Should remove all users that belong to the realm.
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
*/
|
||||||
|
void preRemove(RealmModel realm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an identity provider is removed.
|
||||||
|
* Should remove all federated identities assigned to users from the provider.
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param provider provider model
|
||||||
|
*/
|
||||||
|
void preRemove(RealmModel realm, IdentityProviderModel provider);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a role is removed.
|
||||||
|
* Should remove the role membership for each user.
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param role the role model
|
||||||
|
*/
|
||||||
void preRemove(RealmModel realm, RoleModel role);
|
void preRemove(RealmModel realm, RoleModel role);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a group is removed.
|
||||||
|
* Should remove the group membership for each user.
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param group the group model
|
||||||
|
*/
|
||||||
void preRemove(RealmModel realm, GroupModel group);
|
void preRemove(RealmModel realm, GroupModel group);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a client is removed.
|
||||||
|
* Should remove all user consents associated with the client
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param client the client model
|
||||||
|
*/
|
||||||
void preRemove(RealmModel realm, ClientModel client);
|
void preRemove(RealmModel realm, ClientModel client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a protocolMapper is removed
|
||||||
|
*
|
||||||
|
* @param protocolMapper the protocolMapper model
|
||||||
|
*/
|
||||||
void preRemove(ProtocolMapperModel protocolMapper);
|
void preRemove(ProtocolMapperModel protocolMapper);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a client scope is removed.
|
||||||
|
* Should remove the clientScope from each user consent
|
||||||
|
*
|
||||||
|
* @param clientScope the clientScope model
|
||||||
|
*/
|
||||||
void preRemove(ClientScopeModel clientScope);
|
void preRemove(ClientScopeModel clientScope);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a component is removed.
|
||||||
|
* Should remove all data in UserStorage associated with removed component.
|
||||||
|
* For example,
|
||||||
|
* <ul>
|
||||||
|
* <li>if component corresponds to UserStorageProvider all imported users from the provider should be removed,</li>
|
||||||
|
* <li>if component corresponds to ClientStorageProvider all consents granted for clients imported from the
|
||||||
|
* provider should be removed</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param component the component model
|
||||||
|
*/
|
||||||
|
void preRemove(RealmModel realm, ComponentModel component);
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
void preRemove(RealmModel realm, ComponentModel component);
|
/**
|
||||||
|
* The {@link UserProvider.Streams} interface makes all collection-based methods in {@link UserProvider} default by
|
||||||
|
* providing implementations that delegate to the {@link Stream}-based variants instead of the other way around.
|
||||||
|
* <p/>
|
||||||
|
* It allows for implementations to focus on the {@link Stream}-based approach for processing sets of data and benefit
|
||||||
|
* from the potential memory and performance optimizations of that approach.
|
||||||
|
*/
|
||||||
|
interface Streams extends UserProvider, UserQueryProvider.Streams, UserLookupProvider.Streams {
|
||||||
|
|
||||||
interface Streams extends UserProvider, UserQueryProvider.Streams {
|
|
||||||
@Override
|
@Override
|
||||||
default Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm) {
|
FederatedIdentityModel getFederatedIdentity(RealmModel realm, UserModel user, String socialProvider);
|
||||||
return this.getFederatedIdentitiesStream(user, realm).collect(Collectors.toSet());
|
|
||||||
|
@Override
|
||||||
|
default FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm) {
|
||||||
|
return getFederatedIdentity(realm, user, socialProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm);
|
UserModel getUserByFederatedIdentity(RealmModel realm, FederatedIdentityModel socialLink);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm) {
|
||||||
|
return getUserByFederatedIdentity(realm, socialLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm) {
|
||||||
|
return this.getFederatedIdentitiesStream(realm, user).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel realm, UserModel user);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default List<UserConsentModel> getConsents(RealmModel realm, String userId) {
|
default List<UserConsentModel> getConsents(RealmModel realm, String userId) {
|
||||||
|
@ -209,7 +415,9 @@ public interface UserProvider extends Provider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts);
|
default Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts) {
|
||||||
|
return getUsersStream(realm, null, null, includeServiceAccounts);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults, boolean includeServiceAccounts) {
|
default List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults, boolean includeServiceAccounts) {
|
||||||
|
|
|
@ -22,6 +22,19 @@ import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.provider.Provider;
|
import org.keycloak.provider.Provider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* A class implementing this interface represents a user storage provider to Keycloak.
|
||||||
|
* <p/>
|
||||||
|
* This interface contains only very basic methods for manipulating users. However, the storage provider capabilities
|
||||||
|
* are extended by implementing one or more of the following capability interfaces:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link org.keycloak.storage.user.UserLookupProvider UserLookupProvider} - Provide basic lookup methods. After implementing it is possible to login using users from the storage.</li>
|
||||||
|
* <li>{@link org.keycloak.storage.user.UserQueryProvider UserQueryProvider} - Provide complex lookup methods. After implementing it is possible to manage users from admin console.</li>
|
||||||
|
* <li>{@link org.keycloak.storage.user.UserRegistrationProvider UserRegistrationProvider} - Provide methods for adding users. After implementing it is possible to store registered users in the storage.</li>
|
||||||
|
* <li>{@link org.keycloak.storage.user.UserBulkUpdateProvider UserBulkUpdateProvider} - After implementing it is possible to perform bulk operations on all users from storage (for example, addition of a role to all users).</li>
|
||||||
|
* <li>{@link org.keycloak.storage.user.ImportedUserValidation ImportedUserValidation} - Provider method for validating users within Keycloak local storage that are imported from the storage.</li>
|
||||||
|
* <li>{@link org.keycloak.storage.user.ImportSynchronization ImportSynchronization} - Provider methods for synchronization of the storage with Keycloak local storage. After implementing it is possible to sync users in the Admin console.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -22,6 +22,11 @@ import org.keycloak.storage.UserStorageProviderModel;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
*
|
||||||
|
* This is an optional capability interface that is intended to be implemented by any
|
||||||
|
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports syncing users to keycloak local
|
||||||
|
* storage. You must implement this interface if you want to be able to use sync functionality within the Admin console.
|
||||||
|
*
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,8 +20,12 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If your UserStorageProvider is importing users into local storage, you can validate that import whenever the
|
* This is an optional capability interface that is intended to be implemented by any
|
||||||
* user is queried from local storage.
|
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports validating users. You must
|
||||||
|
* implement this interface if your storage imports users into the Keycloak local storage and you want to sync these
|
||||||
|
* users with your storage. The idea is, that whenever keycloak queries users imported from your storage, the method
|
||||||
|
* {@link #validate(RealmModel, UserModel) validate()} is called and if it returns null, the user is removed from
|
||||||
|
* local storage and reloaded from your storage by corresponding method.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
|
|
|
@ -20,6 +20,9 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This is an optional capability interface that is intended to be implemented by any
|
||||||
|
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports bulk operations.
|
||||||
|
*
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,23 +20,93 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional capability interface implemented by UserStorageProviders. This interface is required
|
* This is an optional capability interface that is intended to be implemented by any
|
||||||
* if you want the UserStorageProvider to support basic login capabilities.
|
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports basic user querying. You must
|
||||||
|
* implement this interface if you want to be able to log in to keycloak using users from your storage.
|
||||||
|
* <p/>
|
||||||
|
* Note that all methods in this interface should limit search only to data available within the storage that is
|
||||||
|
* represented by this provider. They should not lookup other storage providers for additional information.
|
||||||
|
* Optional capability interface implemented by UserStorageProviders.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public interface UserLookupProvider {
|
public interface UserLookupProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a user with the given id belonging to the realm
|
||||||
|
*
|
||||||
|
* @param id id of the user
|
||||||
|
* @param realm the realm model
|
||||||
|
* @return found user model, or {@code null} if no such user exists
|
||||||
|
*/
|
||||||
|
default UserModel getUserById(RealmModel realm, String id) {
|
||||||
|
return getUserById(id, realm);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getUserById(RealmModel, String) getUserById} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
UserModel getUserById(String id, RealmModel realm);
|
UserModel getUserById(String id, RealmModel realm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a user with the given username belonging to the realm
|
||||||
|
*
|
||||||
|
* @param username case insensitive username (case-sensitivity is controlled by storage)
|
||||||
|
* @param realm the realm model
|
||||||
|
* @return found user model, or {@code null} if no such user exists
|
||||||
|
*/
|
||||||
|
default UserModel getUserByUsername(RealmModel realm, String username) {
|
||||||
|
return getUserByUsername(username, realm);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getUserByUsername(RealmModel, String) getUserByUsername} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
UserModel getUserByUsername(String username, RealmModel realm);
|
UserModel getUserByUsername(String username, RealmModel realm);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns a user with the given email belonging to the realm
|
||||||
|
*
|
||||||
|
* @param email case insensitive email address (case-sensitivity is controlled by storage)
|
||||||
|
* @param realm the realm model
|
||||||
|
* @return found user model, or {@code null} if no such user exists
|
||||||
*
|
*
|
||||||
* @param email
|
|
||||||
* @param realm
|
|
||||||
* @throws org.keycloak.models.ModelDuplicateException when there are more users with same email
|
* @throws org.keycloak.models.ModelDuplicateException when there are more users with same email
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
|
default UserModel getUserByEmail(RealmModel realm, String email) {
|
||||||
|
return getUserByEmail(email, realm);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getUserByEmail(RealmModel, String) getUserByEmail} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
UserModel getUserByEmail(String email, RealmModel realm);
|
UserModel getUserByEmail(String email, RealmModel realm);
|
||||||
|
|
||||||
|
interface Streams extends UserLookupProvider {
|
||||||
|
@Override
|
||||||
|
UserModel getUserById(RealmModel realm, String id);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default UserModel getUserById(String id, RealmModel realm) {
|
||||||
|
return getUserById(realm, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
UserModel getUserByUsername(RealmModel realm, String username);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default UserModel getUserByUsername(String username, RealmModel realm) {
|
||||||
|
return getUserByUsername(realm, username);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
UserModel getUserByEmail(RealmModel realm, String email);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default UserModel getUserByEmail(String email, RealmModel realm) {
|
||||||
|
return getUserByEmail(realm, email);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -28,9 +29,13 @@ import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional capability interface implemented by UserStorageProviders.
|
*
|
||||||
* Defines complex queries that are used to locate one or more users. You must implement this interface
|
* This is an optional capability interface that is intended to be implemented by any
|
||||||
* if you want to view and manager users from the administration console.
|
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports complex user querying. You must
|
||||||
|
* implement this interface if you want to view and manage users from the administration console.
|
||||||
|
* <p/>
|
||||||
|
* Note that all methods in this interface should limit search only to data available within the storage that is
|
||||||
|
* represented by this provider. They should not lookup other storage providers for additional information.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
|
@ -43,14 +48,16 @@ public interface UserQueryProvider {
|
||||||
* @param realm the realm
|
* @param realm the realm
|
||||||
* @return the number of users
|
* @return the number of users
|
||||||
*/
|
*/
|
||||||
int getUsersCount(RealmModel realm);
|
default int getUsersCount(RealmModel realm) {
|
||||||
|
return getUsersCount(realm, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of users that are in at least one of the groups
|
* Returns the number of users that are in at least one of the groups
|
||||||
* given.
|
* given.
|
||||||
*
|
*
|
||||||
* @param realm the realm
|
* @param realm the realm
|
||||||
* @param groupIds set of groups id to check for
|
* @param groupIds set of groups IDs, the returned user needs to belong to at least one of them
|
||||||
* @return the number of users that are in at least one of the groups
|
* @return the number of users that are in at least one of the groups
|
||||||
*/
|
*/
|
||||||
default int getUsersCount(RealmModel realm, Set<String> groupIds) {
|
default int getUsersCount(RealmModel realm, Set<String> groupIds) {
|
||||||
|
@ -61,41 +68,64 @@ public interface UserQueryProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of users that match the given criteria.
|
* Returns the number of users that would be returned by a call to {@link #searchForUserStream(RealmModel, String) searchForUserStream}
|
||||||
*
|
*
|
||||||
* @param search search criteria
|
|
||||||
* @param realm the realm
|
* @param realm the realm
|
||||||
|
* @param search case insensitive list of strings separated by whitespaces.
|
||||||
* @return number of users that match the search
|
* @return number of users that match the search
|
||||||
*/
|
*/
|
||||||
default int getUsersCount(String search, RealmModel realm) {
|
default int getUsersCount(RealmModel realm, String search) {
|
||||||
return (int) searchForUserStream(search, realm).count();
|
return getUsersCount(search, realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of users that match the given criteria and are in
|
* @deprecated Use {@link #getUsersCount(RealmModel, String) getUsersCount}
|
||||||
* at least one of the groups given.
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default int getUsersCount(String search, RealmModel realm) {
|
||||||
|
return (int) searchForUserStream(realm, search).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of users that would be returned by a call to {@link #searchForUserStream(RealmModel, String) searchForUserStream}
|
||||||
|
* and are members of at least one of the groups given by the {@code groupIds} set.
|
||||||
*
|
*
|
||||||
* @param search search criteria
|
|
||||||
* @param realm the realm
|
* @param realm the realm
|
||||||
* @param groupIds set of groups to check for
|
* @param search case insensitive list of strings separated by whitespaces.
|
||||||
|
* @param groupIds set of groups IDs, the returned user needs to belong to at least one of them
|
||||||
* @return number of users that match the search and given groups
|
* @return number of users that match the search and given groups
|
||||||
*/
|
*/
|
||||||
|
default int getUsersCount(RealmModel realm, String search, Set<String> groupIds) {
|
||||||
|
return getUsersCount(search, realm, groupIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getUsersCount(RealmModel, String, Set) getUsersCount} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
default int getUsersCount(String search, RealmModel realm, Set<String> groupIds) {
|
default int getUsersCount(String search, RealmModel realm, Set<String> groupIds) {
|
||||||
if (groupIds == null || groupIds.isEmpty()) {
|
if (groupIds == null || groupIds.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return countUsersInGroups(searchForUserStream(search, realm), groupIds);
|
return countUsersInGroups(searchForUserStream(realm, search), groupIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of users that match the given filter parameters.
|
* Returns the number of users that match the given filter parameters.
|
||||||
*
|
*
|
||||||
* @param params filter parameters
|
|
||||||
* @param realm the realm
|
* @param realm the realm
|
||||||
|
* @param params filter parameters
|
||||||
* @return number of users that match the given filters
|
* @return number of users that match the given filters
|
||||||
*/
|
*/
|
||||||
|
default int getUsersCount(RealmModel realm, Map<String, String> params) {
|
||||||
|
return getUsersCount(params, realm);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getUsersCount(RealmModel, Set) getUsersCount} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
default int getUsersCount(Map<String, String> params, RealmModel realm) {
|
default int getUsersCount(Map<String, String> params, RealmModel realm) {
|
||||||
return (int) searchForUserStream(params, realm).count();
|
return (int) searchForUserStream(realm, params).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,13 +137,21 @@ public interface UserQueryProvider {
|
||||||
* @param groupIds set if groups to check for
|
* @param groupIds set if groups to check for
|
||||||
* @return number of users that match the given filters and groups
|
* @return number of users that match the given filters and groups
|
||||||
*/
|
*/
|
||||||
|
default int getUsersCount(RealmModel realm, Map<String, String> params, Set<String> groupIds) {
|
||||||
|
return getUsersCount(params, realm, groupIds);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getUsersCount(RealmModel, Map, Set) getUsersCount} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
default int getUsersCount(Map<String, String> params, RealmModel realm, Set<String> groupIds) {
|
default int getUsersCount(Map<String, String> params, RealmModel realm, Set<String> groupIds) {
|
||||||
if (groupIds == null || groupIds.isEmpty()) {
|
if (groupIds == null || groupIds.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return countUsersInGroups(searchForUserStream(params, realm), groupIds);
|
return countUsersInGroups(searchForUserStream(realm, params), groupIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of users from the given list of users that are in at
|
* Returns the number of users from the given list of users that are in at
|
||||||
* least one of the groups given in the groups set.
|
* least one of the groups given in the groups set.
|
||||||
|
@ -154,7 +192,7 @@ public interface UserQueryProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link #getUsersStream(RealmModel, int, int) getUsersStream} instead.
|
* @deprecated Use {@link #getUsersStream(RealmModel, Integer, Integer) getUsersStream} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults);
|
List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults);
|
||||||
|
@ -163,184 +201,221 @@ public interface UserQueryProvider {
|
||||||
* Searches all users in the realm, starting from the {@code firstResult} and containing at most {@code maxResults}.
|
* Searches all users in the realm, starting from the {@code firstResult} and containing at most {@code maxResults}.
|
||||||
*
|
*
|
||||||
* @param realm a reference to the realm.
|
* @param realm a reference to the realm.
|
||||||
* @param firstResult first result to return. Ignored if negative.
|
* @param firstResult first result to return. Ignored if negative or zero.
|
||||||
* @param maxResults maximum number of results to return. Ignored if negative.
|
* @param maxResults maximum number of results to return. Ignored if negative.
|
||||||
* @return a non-null {@link Stream} of users.
|
* @return a non-null {@link Stream} of users.
|
||||||
*/
|
*/
|
||||||
default Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
|
default Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
List<UserModel> value = this.getUsers(realm, firstResult, maxResults);
|
List<UserModel> value = this.getUsers(realm, firstResult == null ? -1 : firstResult,
|
||||||
|
maxResults == null ? -1 : maxResults);
|
||||||
return value != null ? value.stream() : Stream.empty();
|
return value != null ? value.stream() : Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search for users with username, email or first + last name that is like search string.
|
* Searches for users whose username, email, first name or last name contain any of the strings in {@code search} separated by whitespace.
|
||||||
*
|
* <p/>
|
||||||
* If possible, implementations should treat the parameter values as partial match patterns i.e. in RDMBS terms use LIKE.
|
* If possible, implementations should treat the parameter values as partial match patterns i.e. in RDMBS terms use LIKE.
|
||||||
*
|
* <p/>
|
||||||
* This method is used by the admin console search box
|
* This method is used by the admin console search box
|
||||||
*
|
*
|
||||||
* @param search
|
* @param search case insensitive list of string separated by whitespaces.
|
||||||
* @param realm
|
* @param realm realm to search within
|
||||||
* @return
|
* @return list of users that satisfies the given search condition
|
||||||
* @deprecated Use {@link #searchForUserStream(String, RealmModel) searchForUserStream} instead.
|
*
|
||||||
|
* @deprecated Use {@link #searchForUserStream(RealmModel, String) searchForUserStream} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
List<UserModel> searchForUser(String search, RealmModel realm);
|
List<UserModel> searchForUser(String search, RealmModel realm);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches for users with username, email or first + last name that is like search string. If possible, implementations
|
* Searches for users whose username, email, first name or last name contain any of the strings in {@code search} separated by whitespace.
|
||||||
* should treat the parameter values as partial match patterns (i.e. in RDMBS terms use LIKE).
|
* <p/>
|
||||||
|
* If possible, implementations should treat the parameter values as partial match patterns (i.e. in RDMBS terms use LIKE).
|
||||||
* <p/>
|
* <p/>
|
||||||
* This method is used by the admin console search box
|
* This method is used by the admin console search box
|
||||||
*
|
*
|
||||||
* @param search case sensitive search string.
|
|
||||||
* @param realm a reference to the realm.
|
* @param realm a reference to the realm.
|
||||||
|
* @param search case insensitive list of string separated by whitespaces.
|
||||||
* @return a non-null {@link Stream} of users that match the search string.
|
* @return a non-null {@link Stream} of users that match the search string.
|
||||||
*/
|
*/
|
||||||
default Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
|
default Stream<UserModel> searchForUserStream(RealmModel realm, String search) {
|
||||||
List<UserModel> value = this.searchForUser(search, realm);
|
List<UserModel> value = this.searchForUser(search, realm);
|
||||||
return value != null ? value.stream() : Stream.empty();
|
return value != null ? value.stream() : Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search for users with username, email or first + last name that is like search string.
|
* Searches for users whose username, email, first name or last name contain any of the strings in {@code search} separated by whitespace.
|
||||||
*
|
* The resulting user list should be paginated with respect to parameters {@code firstResult} and {@code maxResults}
|
||||||
|
* <p/>
|
||||||
* If possible, implementations should treat the parameter values as partial match patterns i.e. in RDMBS terms use LIKE.
|
* If possible, implementations should treat the parameter values as partial match patterns i.e. in RDMBS terms use LIKE.
|
||||||
*
|
* <p/>
|
||||||
* This method is used by the admin console search box
|
* This method is used by the admin console search box
|
||||||
*
|
*
|
||||||
* @param search
|
* @param search case insensitive list of string separated by whitespaces.
|
||||||
* @param realm
|
* @param realm a reference to the realm
|
||||||
* @param firstResult
|
* @param firstResult first result to return. Ignored if negative or zero.
|
||||||
* @param maxResults
|
* @param maxResults maximum number of results to return. Ignored if negative.
|
||||||
* @return
|
* @return paginated list of users from the realm that satisfies given search
|
||||||
* @deprecated Use {@link #searchForUserStream(String, RealmModel, Integer, Integer) searchForUserStream} instead.
|
*
|
||||||
|
* @deprecated Use {@link #searchForUserStream(RealmModel, String, Integer, Integer) searchForUserStream} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults);
|
List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches for users with username, email or first + last name that is like search string. If possible, implementations
|
* Searches for users whose username, email, first name or last name contain any of the strings in {@code search} separated by whitespace.
|
||||||
* should treat the parameter values as partial match patterns (i.e. in RDMBS terms use LIKE).
|
* <p/>
|
||||||
|
* If possible, implementations should treat the parameter values as partial match patterns (i.e. in RDMBS terms use LIKE).
|
||||||
* <p/>
|
* <p/>
|
||||||
* This method is used by the admin console search box
|
* This method is used by the admin console search box
|
||||||
*
|
*
|
||||||
* @param search case sensitive search string.
|
|
||||||
* @param realm a reference to the realm.
|
* @param realm a reference to the realm.
|
||||||
* @param firstResult first result to return. Ignored if negative.
|
* @param search case insensitive list of string separated by whitespaces.
|
||||||
* @param maxResults maximum number of results to return. Ignored if negative.
|
* @param firstResult first result to return. Ignored if negative, zero, or {@code null}.
|
||||||
|
* @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
|
||||||
* @return a non-null {@link Stream} of users that match the search criteria.
|
* @return a non-null {@link Stream} of users that match the search criteria.
|
||||||
*/
|
*/
|
||||||
default Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
|
default Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
||||||
List<UserModel> value = this.searchForUser(search, realm, firstResult == null ? -1 : firstResult, maxResults == null ? -1 : maxResults);
|
List<UserModel> value = this.searchForUser(search, realm, firstResult == null ? -1 : firstResult, maxResults == null ? -1 : maxResults);
|
||||||
return value != null ? value.stream() : Stream.empty();
|
return value != null ? value.stream() : Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search for user by parameter. Valid parameters are:
|
* Search for user by a map of parameters.
|
||||||
* "first" - first name
|
* <p/>
|
||||||
* "last" - last name
|
* Valid parameters are:
|
||||||
* "email" - email
|
* <ul>
|
||||||
* "username" - username
|
* <li>{@link UserModel#FIRST_NAME} - first name (case insensitive string)</li>
|
||||||
|
* <li>{@link UserModel#LAST_NAME} - last name (case insensitive string)</li>
|
||||||
|
* <li>{@link UserModel#EMAIL} - email (case insensitive string)</li>
|
||||||
|
* <li>{@link UserModel#USERNAME} - username (case insensitive string)</li>
|
||||||
|
* <li>{@link UserModel#EMAIL_VERIFIED} - search only for users with verified/non-verified email (true/false)</li>
|
||||||
|
* <li>{@link UserModel#ENABLED} - search only for enabled/disabled users (true/false)</li>
|
||||||
|
* <li>{@link UserModel#IDP_ALIAS} - search only for users that have a federated identity
|
||||||
|
* from idp with the given alias configured (case sensitive string)</li>
|
||||||
|
* <li>{@link UserModel#IDP_USER_ID} - search for users with federated identity with
|
||||||
|
* the given userId (case sensitive string)</li>
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* If possible, implementations should treat the parameter values as partial match patterns i.e. in RDMBS terms use LIKE.
|
* If possible, implementations should treat the parameter values as partial match patterns i.e. in RDMBS terms use LIKE.
|
||||||
*
|
* <p/>
|
||||||
* This method is used by the REST API when querying users.
|
* This method is used by the REST API when querying users.
|
||||||
*
|
*
|
||||||
|
* @param params a map containing the search parameters
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @return list of users that satisfies given search conditions
|
||||||
*
|
*
|
||||||
* @param params
|
* @deprecated Use {@link #searchForUserStream(RealmModel, Map) searchForUserStream} instead.
|
||||||
* @param realm
|
|
||||||
* @return
|
|
||||||
* @deprecated Use {@link #searchForUserStream(Map, RealmModel) searchForUserStream} instead.
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
List<UserModel> searchForUser(Map<String, String> params, RealmModel realm);
|
List<UserModel> searchForUser(Map<String, String> params, RealmModel realm);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches for user by parameter. If possible, implementations should treat the parameter values as partial match patterns
|
* Searches for user by parameter.
|
||||||
* (i.e. in RDMBS terms use LIKE). Valid parameters are:
|
* If possible, implementations should treat the parameter values as partial match patterns (i.e. in RDMBS terms use LIKE).
|
||||||
|
* <p/>
|
||||||
|
* Valid parameters are:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><b>first</b> - first name</li>
|
* <li>{@link UserModel#FIRST_NAME} - first name (case insensitive string)</li>
|
||||||
* <li><b>last</b> - last name</li>
|
* <li>{@link UserModel#LAST_NAME} - last name (case insensitive string)</li>
|
||||||
* <li><b>email</b> - email</li>
|
* <li>{@link UserModel#EMAIL} - email (case insensitive string)</li>
|
||||||
* <li><b>username</b> - username</li>
|
* <li>{@link UserModel#USERNAME} - username (case insensitive string)</li>
|
||||||
* <li><b>enabled</b> - if user is enabled (true/false)</li>
|
* <li>{@link UserModel#EMAIL_VERIFIED} - search only for users with verified/non-verified email (true/false)</li>
|
||||||
|
* <li>{@link UserModel#ENABLED} - search only for enabled/disabled users (true/false)</li>
|
||||||
|
* <li>{@link UserModel#IDP_ALIAS} - search only for users that have a federated identity
|
||||||
|
* from idp with the given alias configured (case sensitive string)</li>
|
||||||
|
* <li>{@link UserModel#IDP_USER_ID} - search for users with federated identity with
|
||||||
|
* the given userId (case sensitive string)</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
|
*
|
||||||
* This method is used by the REST API when querying users.
|
* This method is used by the REST API when querying users.
|
||||||
*
|
*
|
||||||
* @param params a map containing the search parameters.
|
|
||||||
* @param realm a reference to the realm.
|
* @param realm a reference to the realm.
|
||||||
|
* @param params a map containing the search parameters.
|
||||||
* @return a non-null {@link Stream} of users that match the search parameters.
|
* @return a non-null {@link Stream} of users that match the search parameters.
|
||||||
*/
|
*/
|
||||||
default Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm) {
|
default Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params) {
|
||||||
List<UserModel> value = this.searchForUser(params, realm);
|
List<UserModel> value = this.searchForUser(params, realm);
|
||||||
return value != null ? value.stream() : Stream.empty();
|
return value != null ? value.stream() : Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search for user by parameter. Valid parameters are:
|
* Search for user by parameter.
|
||||||
* "first" - first name
|
* <p/>
|
||||||
* "last" - last name
|
* Valid parameters are:
|
||||||
* "email" - email
|
* <ul>
|
||||||
* "username" - username
|
* <li>{@link UserModel#FIRST_NAME} - first name (case insensitive string)</li>
|
||||||
* "enabled" - is user enabled (true/false)
|
* <li>{@link UserModel#LAST_NAME} - last name (case insensitive string)</li>
|
||||||
|
* <li>{@link UserModel#EMAIL} - email (case insensitive string)</li>
|
||||||
|
* <li>{@link UserModel#USERNAME} - username (case insensitive string)</li>
|
||||||
|
* <li>{@link UserModel#EMAIL_VERIFIED} - search only for users with verified/non-verified email (true/false)</li>
|
||||||
|
* <li>{@link UserModel#ENABLED} - search only for enabled/disabled users (true/false)</li>
|
||||||
|
* <li>{@link UserModel#IDP_ALIAS} - search only for users that have a federated identity
|
||||||
|
* from idp with the given alias configured (case sensitive string)</li>
|
||||||
|
* <li>{@link UserModel#IDP_USER_ID} - search for users with federated identity with
|
||||||
|
* the given userId (case sensitive string)</li>
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* If possible, implementations should treat the parameter values as patterns i.e. in RDMBS terms use LIKE.
|
* If possible, implementations should treat the parameter values as patterns i.e. in RDMBS terms use LIKE.
|
||||||
|
* <p/>
|
||||||
* This method is used by the REST API when querying users.
|
* This method is used by the REST API when querying users.
|
||||||
*
|
*
|
||||||
|
* @param params a map containing the search parameters.
|
||||||
|
* @param realm a reference to the realm.
|
||||||
|
* @param firstResult first result to return. Ignored if negative.
|
||||||
|
* @param maxResults maximum number of results to return. Ignored if negative.
|
||||||
|
* @return a non-null {@link Stream} of users that match the search criteria.
|
||||||
*
|
*
|
||||||
* @param params
|
* @deprecated Use {@link #searchForUserStream(RealmModel, Map, Integer, Integer) searchForUserStream} instead.
|
||||||
* @param realm
|
|
||||||
* @param firstResult
|
|
||||||
* @param maxResults
|
|
||||||
* @return
|
|
||||||
* @deprecated Use {@link #searchForUserStream(Map, RealmModel, Integer, Integer) searchForUserStream} instead.
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
List<UserModel> searchForUser(Map<String, String> params, RealmModel realm, int firstResult, int maxResults);
|
List<UserModel> searchForUser(Map<String, String> params, RealmModel realm, int firstResult, int maxResults);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches for user by parameter. If possible, implementations should treat the parameter values as partial match patterns
|
* Searches for user by parameter. If possible, implementations should treat the parameter values as partial match patterns
|
||||||
* (i.e. in RDMBS terms use LIKE). Valid parameters are:
|
* (i.e. in RDMBS terms use LIKE).
|
||||||
|
* <p/>
|
||||||
|
* Valid parameters are:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><b>first</b> - first name</li>
|
* <li>{@link UserModel#FIRST_NAME} - first name (case insensitive string)</li>
|
||||||
* <li><b>last</b> - last name</li>
|
* <li>{@link UserModel#LAST_NAME} - last name (case insensitive string)</li>
|
||||||
* <li><b>email</b> - email</li>
|
* <li>{@link UserModel#EMAIL} - email (case insensitive string)</li>
|
||||||
* <li><b>username</b> - username</li>
|
* <li>{@link UserModel#USERNAME} - username (case insensitive string)</li>
|
||||||
* <li><b>enabled</b> - if user is enabled (true/false)</li>
|
* <li>{@link UserModel#EMAIL_VERIFIED} - search only for users with verified/non-verified email (true/false)</li>
|
||||||
|
* <li>{@link UserModel#ENABLED} - search only for enabled/disabled users (true/false)</li>
|
||||||
|
* <li>{@link UserModel#IDP_ALIAS} - search only for users that have a federated identity
|
||||||
|
* from idp with the given alias configured (case sensitive string)</li>
|
||||||
|
* <li>{@link UserModel#IDP_USER_ID} - search for users with federated identity with
|
||||||
|
* the given userId (case sensitive string)</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
|
*
|
||||||
* This method is used by the REST API when querying users.
|
* This method is used by the REST API when querying users.
|
||||||
*
|
*
|
||||||
* @param params a map containing the search parameters.
|
|
||||||
* @param realm a reference to the realm.
|
* @param realm a reference to the realm.
|
||||||
* @param firstResult first result to return. Ignored if negative.
|
* @param params a map containing the search parameters.
|
||||||
* @param maxResults maximum number of results to return. Ignored if negative.
|
* @param firstResult first result to return. Ignored if negative, zero, or {@code null}.
|
||||||
|
* @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
|
||||||
* @return a non-null {@link Stream} of users that match the search criteria.
|
* @return a non-null {@link Stream} of users that match the search criteria.
|
||||||
*/
|
*/
|
||||||
default Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm, Integer firstResult, Integer maxResults) {
|
default Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params, Integer firstResult, Integer maxResults) {
|
||||||
List<UserModel> value = this.searchForUser(params, realm, firstResult == null ? -1 : firstResult, maxResults == null ? -1 : maxResults);
|
List<UserModel> value = this.searchForUser(params, realm, firstResult == null ? -1 : firstResult, maxResults == null ? -1 : maxResults);
|
||||||
return value != null ? value.stream() : Stream.empty();
|
return value != null ? value.stream() : Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get users that belong to a specific group. Implementations do not have to search in UserFederatedStorageProvider
|
* Get users that belong to a specific group.
|
||||||
* as this is done automatically.
|
|
||||||
*
|
*
|
||||||
* @see org.keycloak.storage.federated.UserFederatedStorageProvider
|
* @param realm a reference to the realm
|
||||||
|
* @param group a reference to the group
|
||||||
|
* @return a list of all users that are members of the given group
|
||||||
*
|
*
|
||||||
* @param realm
|
|
||||||
* @param group
|
|
||||||
* @return
|
|
||||||
* @deprecated Use {@link #getGroupMembersStream(RealmModel, GroupModel) getGroupMembersStream} instead.
|
* @deprecated Use {@link #getGroupMembersStream(RealmModel, GroupModel) getGroupMembersStream} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
List<UserModel> getGroupMembers(RealmModel realm, GroupModel group);
|
List<UserModel> getGroupMembers(RealmModel realm, GroupModel group);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains users that belong to a specific group. Implementations do not have to search in {@code UserFederatedStorageProvider}
|
* Obtains users that belong to a specific group.
|
||||||
* as this is done automatically.
|
|
||||||
*
|
|
||||||
* @see org.keycloak.storage.federated.UserFederatedStorageProvider
|
|
||||||
*
|
*
|
||||||
* @param realm a reference to the realm.
|
* @param realm a reference to the realm.
|
||||||
* @param group a reference to the group.
|
* @param group a reference to the group.
|
||||||
|
@ -352,31 +427,26 @@ public interface UserQueryProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get users that belong to a specific group. Implementations do not have to search in UserFederatedStorageProvider
|
* Gets paginated list of users that belong to a specific group.
|
||||||
* as this is done automatically.
|
|
||||||
*
|
*
|
||||||
* @see org.keycloak.storage.federated.UserFederatedStorageProvider
|
* @param realm a reference to the realm
|
||||||
|
* @param group a reference to the group
|
||||||
|
* @param firstResult first result to return. Ignored if negative or zero.
|
||||||
|
* @param maxResults maximum number of results to return. Ignored if negative.
|
||||||
|
* @return paginated list of members of the given group
|
||||||
*
|
*
|
||||||
* @param realm
|
|
||||||
* @param group
|
|
||||||
* @param firstResult
|
|
||||||
* @param maxResults
|
|
||||||
* @return
|
|
||||||
* @deprecated Use {@link #getGroupMembersStream(RealmModel, GroupModel, Integer, Integer) getGroupMembersStream} instead.
|
* @deprecated Use {@link #getGroupMembersStream(RealmModel, GroupModel, Integer, Integer) getGroupMembersStream} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults);
|
List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains users that belong to a specific group. Implementations do not have to search in {@code UserFederatedStorageProvider}
|
* Obtains users that belong to a specific group.
|
||||||
* as this is done automatically.
|
|
||||||
*
|
|
||||||
* @see org.keycloak.storage.federated.UserFederatedStorageProvider
|
|
||||||
*
|
*
|
||||||
* @param realm a reference to the realm.
|
* @param realm a reference to the realm.
|
||||||
* @param group a reference to the group.
|
* @param group a reference to the group.
|
||||||
* @param firstResult first result to return. Ignored if negative.
|
* @param firstResult first result to return. Ignored if negative, zero, or {@code null}.
|
||||||
* @param maxResults maximum number of results to return. Ignored if negative.
|
* @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
|
||||||
* @return a non-null {@link Stream} of users that belong to the group.
|
* @return a non-null {@link Stream} of users that belong to the group.
|
||||||
*/
|
*/
|
||||||
default Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
|
default Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
|
||||||
|
@ -387,9 +457,10 @@ public interface UserQueryProvider {
|
||||||
/**
|
/**
|
||||||
* Get users that belong to a specific role.
|
* Get users that belong to a specific role.
|
||||||
*
|
*
|
||||||
* @param realm
|
* @param realm a reference to the realm
|
||||||
* @param role
|
* @param role a reference to the role
|
||||||
* @return
|
* @return a list of users that has the given role assigned
|
||||||
|
*
|
||||||
* @deprecated Use {@link #getRoleMembersStream(RealmModel, RoleModel) getRoleMembersStream} instead.
|
* @deprecated Use {@link #getRoleMembersStream(RealmModel, RoleModel) getRoleMembersStream} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
@ -411,15 +482,17 @@ public interface UserQueryProvider {
|
||||||
/**
|
/**
|
||||||
* Search for users that have a specific role with a specific roleId.
|
* Search for users that have a specific role with a specific roleId.
|
||||||
*
|
*
|
||||||
* @param role
|
* @param realm a reference to the realm
|
||||||
* @param firstResult
|
* @param role a reference to the role
|
||||||
* @param maxResults
|
* @param firstResult first result to return. Ignored if negative or zero.
|
||||||
* @return
|
* @param maxResults maximum number of results to return. Ignored if negative.
|
||||||
|
* @return a paginated list of users that has the given role assigned
|
||||||
|
*
|
||||||
* @deprecated Use {@link #getRoleMembersStream(RealmModel, RoleModel, Integer, Integer) getRoleMembersStream} instead.
|
* @deprecated Use {@link #getRoleMembersStream(RealmModel, RoleModel, Integer, Integer) getRoleMembersStream} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
default List<UserModel> getRoleMembers(RealmModel realm, RoleModel role, int firstResult, int maxResults) {
|
default List<UserModel> getRoleMembers(RealmModel realm, RoleModel role, int firstResult, int maxResults) {
|
||||||
return this.getRoleMembersStream(realm, role, firstResult, maxResults).collect(Collectors.toList());
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -432,38 +505,33 @@ public interface UserQueryProvider {
|
||||||
* @return a non-null {@link Stream} of users that have the specified role.
|
* @return a non-null {@link Stream} of users that have the specified role.
|
||||||
*/
|
*/
|
||||||
default Stream<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults) {
|
default Stream<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults) {
|
||||||
return Stream.empty();
|
return getRoleMembers(realm, role, firstResult == null ? -1 : firstResult, maxResults== null ? -1 : maxResults)
|
||||||
|
.stream();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search for users that have a specific attribute with a specific value.
|
* Search for users that have a specific attribute with a specific value.
|
||||||
* Implementations do not have to search in UserFederatedStorageProvider
|
|
||||||
* as this is done automatically.
|
|
||||||
*
|
*
|
||||||
* @see org.keycloak.storage.federated.UserFederatedStorageProvider
|
* @param attrName a name of the attribute that will be searched
|
||||||
|
* @param attrValue a value of the attribute that will be searched
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @return list of users with the given attribute name and value
|
||||||
*
|
*
|
||||||
* @param attrName
|
* @deprecated Use {@link #searchForUserByUserAttributeStream(RealmModel, String, String) searchForUserByUserAttributeStream}
|
||||||
* @param attrValue
|
|
||||||
* @param realm
|
|
||||||
* @return
|
|
||||||
* @deprecated Use {@link #searchForUserByUserAttributeStream(String, String, RealmModel) searchForUserByUserAttributeStream}
|
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm);
|
List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches for users that have a specific attribute with a specific value. Implementations do not have to search in
|
* Searches for users that have a specific attribute with a specific value.
|
||||||
* {@code UserFederatedStorageProvider} as this is done automatically.
|
|
||||||
*
|
|
||||||
* @see org.keycloak.storage.federated.UserFederatedStorageProvider
|
|
||||||
*
|
*
|
||||||
|
* @param realm a reference to the realm.
|
||||||
* @param attrName the attribute name.
|
* @param attrName the attribute name.
|
||||||
* @param attrValue the attribute value.
|
* @param attrValue the attribute value.
|
||||||
* @param realm a reference to the realm.
|
|
||||||
* @return a non-null {@link Stream} of users that match the search criteria.
|
* @return a non-null {@link Stream} of users that match the search criteria.
|
||||||
*/
|
*/
|
||||||
default Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
|
default Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
|
||||||
List<UserModel> value = this.searchForUserByUserAttribute(attrName, attrValue, realm);
|
List<UserModel> value = this.searchForUserByUserAttribute(attrName, attrValue, realm);
|
||||||
return value != null ? value.stream() : Stream.empty();
|
return value != null ? value.stream() : Stream.empty();
|
||||||
}
|
}
|
||||||
|
@ -476,13 +544,62 @@ public interface UserQueryProvider {
|
||||||
* from the potential memory and performance optimizations of that approach.
|
* from the potential memory and performance optimizations of that approach.
|
||||||
*/
|
*/
|
||||||
interface Streams extends UserQueryProvider {
|
interface Streams extends UserQueryProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default int getUsersCount(RealmModel realm, String search) {
|
||||||
|
return (int) searchForUserStream(realm, search).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default int getUsersCount(String search, RealmModel realm) {
|
||||||
|
return getUsersCount(realm, search);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default int getUsersCount(RealmModel realm, String search, Set<String> groupIds) {
|
||||||
|
if (groupIds == null || groupIds.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return countUsersInGroups(searchForUserStream(realm, search), groupIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default int getUsersCount(String search, RealmModel realm, Set<String> groupIds) {
|
||||||
|
return getUsersCount(realm, search, groupIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default int getUsersCount(RealmModel realm, Map<String, String> params) {
|
||||||
|
return (int) searchForUserStream(realm, params).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default int getUsersCount( Map<String, String> params, RealmModel realm) {
|
||||||
|
return getUsersCount(realm, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default int getUsersCount(RealmModel realm, Map<String, String> params, Set<String> groupIds) {
|
||||||
|
if (groupIds == null || groupIds.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return countUsersInGroups(searchForUserStream(realm, params), groupIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default int getUsersCount(Map<String, String> params, RealmModel realm, Set<String> groupIds) {
|
||||||
|
return getUsersCount(realm, params, groupIds);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default List<UserModel> getUsers(RealmModel realm) {
|
default List<UserModel> getUsers(RealmModel realm) {
|
||||||
return this.getUsersStream(realm).collect(Collectors.toList());
|
return this.getUsersStream(realm).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Stream<UserModel> getUsersStream(RealmModel realm);
|
default Stream<UserModel> getUsersStream(RealmModel realm) {
|
||||||
|
return getUsersStream(realm, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
|
default List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
|
||||||
|
@ -490,39 +607,43 @@ public interface UserQueryProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults);
|
Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default List<UserModel> searchForUser(String search, RealmModel realm) {
|
default List<UserModel> searchForUser(String search, RealmModel realm) {
|
||||||
return this.searchForUserStream(search, realm).collect(Collectors.toList());
|
return this.searchForUserStream(realm, search).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Stream<UserModel> searchForUserStream(String search, RealmModel realm);
|
default Stream<UserModel> searchForUserStream(RealmModel realm, String search) {
|
||||||
|
return searchForUserStream(realm, search, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
|
default List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
|
||||||
return this.searchForUserStream(search, realm, firstResult, maxResults).collect(Collectors.toList());
|
return this.searchForUserStream(realm, search, firstResult, maxResults).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults);
|
Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default List<UserModel> searchForUser(Map<String, String> params, RealmModel realm) {
|
default List<UserModel> searchForUser(Map<String, String> params, RealmModel realm) {
|
||||||
return this.searchForUserStream(params, realm).collect(Collectors.toList());
|
return this.searchForUserStream(realm, params).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm);
|
default Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params) {
|
||||||
|
return searchForUserStream(realm, params, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default List<UserModel> searchForUser(Map<String, String> params, RealmModel realm, int firstResult, int maxResults) {
|
default List<UserModel> searchForUser(Map<String, String> params, RealmModel realm, int firstResult, int maxResults) {
|
||||||
return this.searchForUserStream(params, realm, firstResult, maxResults).collect(Collectors.toList());
|
return this.searchForUserStream(realm, params, firstResult, maxResults).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm, Integer firstResult, Integer maxResults);
|
Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params, Integer firstResult, Integer maxResults);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default List<UserModel> getGroupMembers(RealmModel realm, GroupModel group) {
|
default List<UserModel> getGroupMembers(RealmModel realm, GroupModel group) {
|
||||||
|
@ -530,7 +651,9 @@ public interface UserQueryProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group);
|
default Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
|
||||||
|
return this.getGroupMembersStream(realm, group, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) {
|
default List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) {
|
||||||
|
@ -542,10 +665,10 @@ public interface UserQueryProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
|
default List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
|
||||||
return this.searchForUserByUserAttributeStream(attrName, attrValue, realm).collect(Collectors.toList());
|
return this.searchForUserByUserAttributeStream(realm, attrName, attrValue).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm);
|
Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,9 @@ import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional capability interface implemented by UserStorageProviders.
|
* This is an optional capability interface that is intended to be implemented by any
|
||||||
* Implement this interface if your provider supports adding and removing users.
|
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports addition of new users. You must
|
||||||
|
* implement this interface if you want to use this storage for registering new users.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
|
@ -37,9 +38,9 @@ public interface UserRegistrationProvider {
|
||||||
* Returning null is useful when you want optional support for adding users. For example,
|
* 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.
|
* our LDAP provider can enable and disable the ability to add users.
|
||||||
*
|
*
|
||||||
* @param realm
|
* @param realm a reference to the realm
|
||||||
* @param username
|
* @param username a username the created user will be assigned
|
||||||
* @return
|
* @return a model of created user
|
||||||
*/
|
*/
|
||||||
UserModel addUser(RealmModel realm, String username);
|
UserModel addUser(RealmModel realm, String username);
|
||||||
|
|
||||||
|
@ -54,9 +55,9 @@ public interface UserRegistrationProvider {
|
||||||
* this method will be called before local storage's removeUser() method is invoked. Also,
|
* 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.
|
* you DO NOT need to remove the imported user. The runtime will handle this for you.
|
||||||
*
|
*
|
||||||
* @param realm
|
* @param realm a reference to the realm
|
||||||
* @param user
|
* @param user a reference to the user that is removed
|
||||||
* @return
|
* @return true if the user was removed, false otherwise
|
||||||
*/
|
*/
|
||||||
boolean removeUser(RealmModel realm, UserModel user);
|
boolean removeUser(RealmModel realm, UserModel user);
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ public abstract class AbstractIdpAuthenticator implements Authenticator {
|
||||||
|
|
||||||
ExistingUserInfo duplication = ExistingUserInfo.deserialize(existingUserId);
|
ExistingUserInfo duplication = ExistingUserInfo.deserialize(existingUserId);
|
||||||
|
|
||||||
UserModel existingUser = session.users().getUserById(duplication.getExistingUserId(), realm);
|
UserModel existingUser = session.users().getUserById(realm, duplication.getExistingUserId());
|
||||||
if (existingUser == null) {
|
if (existingUser == null) {
|
||||||
throw new AuthenticationFlowException("User with ID '" + existingUserId + "' not found.", AuthenticationFlowError.INVALID_USER);
|
throw new AuthenticationFlowException("User with ID '" + existingUserId + "' not found.", AuthenticationFlowError.INVALID_USER);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,13 +120,13 @@ public class IdpCreateUserIfUniqueAuthenticator extends AbstractIdpAuthenticator
|
||||||
protected ExistingUserInfo checkExistingUser(AuthenticationFlowContext context, String username, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext) {
|
protected ExistingUserInfo checkExistingUser(AuthenticationFlowContext context, String username, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext) {
|
||||||
|
|
||||||
if (brokerContext.getEmail() != null && !context.getRealm().isDuplicateEmailsAllowed()) {
|
if (brokerContext.getEmail() != null && !context.getRealm().isDuplicateEmailsAllowed()) {
|
||||||
UserModel existingUser = context.getSession().users().getUserByEmail(brokerContext.getEmail(), context.getRealm());
|
UserModel existingUser = context.getSession().users().getUserByEmail(context.getRealm(), brokerContext.getEmail());
|
||||||
if (existingUser != null) {
|
if (existingUser != null) {
|
||||||
return new ExistingUserInfo(existingUser.getId(), UserModel.EMAIL, existingUser.getEmail());
|
return new ExistingUserInfo(existingUser.getId(), UserModel.EMAIL, existingUser.getEmail());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UserModel existingUser = context.getSession().users().getUserByUsername(username, context.getRealm());
|
UserModel existingUser = context.getSession().users().getUserByUsername(context.getRealm(), username);
|
||||||
if (existingUser != null) {
|
if (existingUser != null) {
|
||||||
return new ExistingUserInfo(existingUser.getId(), UserModel.USERNAME, existingUser.getUsername());
|
return new ExistingUserInfo(existingUser.getId(), UserModel.USERNAME, existingUser.getUsername());
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ public class WebAuthnAuthenticator implements Authenticator, CredentialValidator
|
||||||
String userVerificationRequirement = getWebAuthnPolicy(context).getUserVerificationRequirement();
|
String userVerificationRequirement = getWebAuthnPolicy(context).getUserVerificationRequirement();
|
||||||
if (WebAuthnConstants.OPTION_REQUIRED.equals(userVerificationRequirement)) isUVFlagChecked = true;
|
if (WebAuthnConstants.OPTION_REQUIRED.equals(userVerificationRequirement)) isUVFlagChecked = true;
|
||||||
|
|
||||||
UserModel user = session.users().getUserById(userId, context.getRealm());
|
UserModel user = session.users().getUserById(context.getRealm(), userId);
|
||||||
|
|
||||||
AuthenticationRequest authenticationRequest = new AuthenticationRequest(
|
AuthenticationRequest authenticationRequest = new AuthenticationRequest(
|
||||||
credentialId,
|
credentialId,
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class ResetCredentialChooseUser implements Authenticator, AuthenticatorFa
|
||||||
|
|
||||||
String actionTokenUserId = context.getAuthenticationSession().getAuthNote(DefaultActionTokenKey.ACTION_TOKEN_USER_ID);
|
String actionTokenUserId = context.getAuthenticationSession().getAuthNote(DefaultActionTokenKey.ACTION_TOKEN_USER_ID);
|
||||||
if (actionTokenUserId != null) {
|
if (actionTokenUserId != null) {
|
||||||
UserModel existingUser = context.getSession().users().getUserById(actionTokenUserId, context.getRealm());
|
UserModel existingUser = context.getSession().users().getUserById(context.getRealm(), actionTokenUserId);
|
||||||
|
|
||||||
// Action token logics handles checks for user ID validity and user being enabled
|
// Action token logics handles checks for user ID validity and user being enabled
|
||||||
|
|
||||||
|
@ -96,9 +96,9 @@ public class ResetCredentialChooseUser implements Authenticator, AuthenticatorFa
|
||||||
username = username.trim();
|
username = username.trim();
|
||||||
|
|
||||||
RealmModel realm = context.getRealm();
|
RealmModel realm = context.getRealm();
|
||||||
UserModel user = context.getSession().users().getUserByUsername(username, realm);
|
UserModel user = context.getSession().users().getUserByUsername(realm, username);
|
||||||
if (user == null && realm.isLoginWithEmailAllowed() && username.contains("@")) {
|
if (user == null && realm.isLoginWithEmailAllowed() && username.contains("@")) {
|
||||||
user = context.getSession().users().getUserByEmail(username, realm);
|
user = context.getSession().users().getUserByEmail(realm, username);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.getAuthenticationSession().setAuthNote(AbstractUsernameFormAuthenticator.ATTEMPTED_USERNAME, username);
|
context.getAuthenticationSession().setAuthNote(AbstractUsernameFormAuthenticator.ATTEMPTED_USERNAME, username);
|
||||||
|
|
|
@ -63,7 +63,7 @@ public abstract class UserIdentityToModelMapper {
|
||||||
if (_customAttributes.isEmpty() || userIdentityValues.isEmpty() || (_customAttributes.size() != userIdentityValues.size())) {
|
if (_customAttributes.isEmpty() || userIdentityValues.isEmpty() || (_customAttributes.size() != userIdentityValues.size())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Stream<UserModel> usersStream = session.users().searchForUserByUserAttributeStream(_customAttributes.get(0), userIdentityValues.get(0), context.getRealm());
|
Stream<UserModel> usersStream = session.users().searchForUserByUserAttributeStream(context.getRealm(), _customAttributes.get(0), userIdentityValues.get(0));
|
||||||
|
|
||||||
for (int i = 1; i <_customAttributes.size(); ++i) {
|
for (int i = 1; i <_customAttributes.size(); ++i) {
|
||||||
String customAttribute = _customAttributes.get(i);
|
String customAttribute = _customAttributes.get(i);
|
||||||
|
|
|
@ -244,10 +244,10 @@ public class PolicyEvaluationService {
|
||||||
|
|
||||||
UserSessionModel userSession = null;
|
UserSessionModel userSession = null;
|
||||||
if (subject != null) {
|
if (subject != null) {
|
||||||
UserModel userModel = keycloakSession.users().getUserById(subject, realm);
|
UserModel userModel = keycloakSession.users().getUserById(realm, subject);
|
||||||
|
|
||||||
if (userModel == null) {
|
if (userModel == null) {
|
||||||
userModel = keycloakSession.users().getUserByUsername(subject, realm);
|
userModel = keycloakSession.users().getUserByUsername(realm, subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userModel != null) {
|
if (userModel != null) {
|
||||||
|
|
|
@ -387,7 +387,7 @@ public class ResourceSetService {
|
||||||
if (clientModel != null) {
|
if (clientModel != null) {
|
||||||
owner = clientModel.getId();
|
owner = clientModel.getId();
|
||||||
} else {
|
} else {
|
||||||
UserModel user = authorization.getKeycloakSession().users().getUserByUsername(owner, realm);
|
UserModel user = authorization.getKeycloakSession().users().getUserByUsername(realm, owner);
|
||||||
|
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
owner = user.getId();
|
owner = user.getId();
|
||||||
|
|
|
@ -199,8 +199,8 @@ public class PolicyEvaluationResponseBuilder {
|
||||||
KeycloakSession keycloakSession = authorization.getKeycloakSession();
|
KeycloakSession keycloakSession = authorization.getKeycloakSession();
|
||||||
RealmModel realm = authorization.getRealm();
|
RealmModel realm = authorization.getRealm();
|
||||||
PermissionTicket ticket = tickets.get(0);
|
PermissionTicket ticket = tickets.get(0);
|
||||||
UserModel userOwner = keycloakSession.users().getUserById(ticket.getOwner(), realm);
|
UserModel userOwner = keycloakSession.users().getUserById(realm, ticket.getOwner());
|
||||||
UserModel requester = keycloakSession.users().getUserById(ticket.getRequester(), realm);
|
UserModel requester = keycloakSession.users().getUserById(realm, ticket.getRequester());
|
||||||
String resourceOwner;
|
String resourceOwner;
|
||||||
if (userOwner != null) {
|
if (userOwner != null) {
|
||||||
resourceOwner = getUserEmailOrUserName(userOwner);
|
resourceOwner = getUserEmailOrUserName(userOwner);
|
||||||
|
|
|
@ -91,9 +91,9 @@ public class PermissionTicketService {
|
||||||
|
|
||||||
UserModel user = null;
|
UserModel user = null;
|
||||||
if(representation.getRequester() != null)
|
if(representation.getRequester() != null)
|
||||||
user = this.authorization.getKeycloakSession().userStorageManager().getUserById(representation.getRequester(), this.authorization.getRealm());
|
user = this.authorization.getKeycloakSession().userStorageManager().getUserById(this.authorization.getRealm(), representation.getRequester());
|
||||||
else
|
else
|
||||||
user = this.authorization.getKeycloakSession().userStorageManager().getUserByUsername(representation.getRequesterName(), this.authorization.getRealm());
|
user = this.authorization.getKeycloakSession().userStorageManager().getUserByUsername(this.authorization.getRealm(), representation.getRequesterName());
|
||||||
|
|
||||||
if (user == null)
|
if (user == null)
|
||||||
throw new ErrorResponseException("invalid_permission", "Requester does not exists in this server as user.", Response.Status.BAD_REQUEST);
|
throw new ErrorResponseException("invalid_permission", "Requester does not exists in this server as user.", Response.Status.BAD_REQUEST);
|
||||||
|
@ -229,13 +229,13 @@ public class PermissionTicketService {
|
||||||
private String getUserId(String userIdOrName) {
|
private String getUserId(String userIdOrName) {
|
||||||
UserProvider userProvider = authorization.getKeycloakSession().users();
|
UserProvider userProvider = authorization.getKeycloakSession().users();
|
||||||
RealmModel realm = authorization.getRealm();
|
RealmModel realm = authorization.getRealm();
|
||||||
UserModel userModel = userProvider.getUserById(userIdOrName, realm);
|
UserModel userModel = userProvider.getUserById(realm, userIdOrName);
|
||||||
|
|
||||||
if (userModel != null) {
|
if (userModel != null) {
|
||||||
return userModel.getId();
|
return userModel.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
userModel = userProvider.getUserByUsername(userIdOrName, realm);
|
userModel = userProvider.getUserByUsername(realm, userIdOrName);
|
||||||
|
|
||||||
if (userModel != null) {
|
if (userModel != null) {
|
||||||
return userModel.getId();
|
return userModel.getId();
|
||||||
|
|
|
@ -250,7 +250,7 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Response exchangeStoredToken(UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject) {
|
protected Response exchangeStoredToken(UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject) {
|
||||||
FederatedIdentityModel model = session.users().getFederatedIdentity(tokenSubject, getConfig().getAlias(), authorizedClient.getRealm());
|
FederatedIdentityModel model = session.users().getFederatedIdentity(authorizedClient.getRealm(), tokenSubject, getConfig().getAlias());
|
||||||
if (model == null || model.getToken() == null) {
|
if (model == null || model.getToken() == null) {
|
||||||
event.detail(Details.REASON, "requested_issuer is not linked");
|
event.detail(Details.REASON, "requested_issuer is not linked");
|
||||||
event.error(Errors.INVALID_TOKEN);
|
event.error(Errors.INVALID_TOKEN);
|
||||||
|
|
|
@ -169,7 +169,7 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Response exchangeStoredToken(UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject) {
|
protected Response exchangeStoredToken(UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject) {
|
||||||
FederatedIdentityModel model = session.users().getFederatedIdentity(tokenSubject, getConfig().getAlias(), authorizedClient.getRealm());
|
FederatedIdentityModel model = session.users().getFederatedIdentity(authorizedClient.getRealm(), tokenSubject, getConfig().getAlias());
|
||||||
if (model == null || model.getToken() == null) {
|
if (model == null || model.getToken() == null) {
|
||||||
event.detail(Details.REASON, "requested_issuer is not linked");
|
event.detail(Details.REASON, "requested_issuer is not linked");
|
||||||
event.error(Errors.INVALID_TOKEN);
|
event.error(Errors.INVALID_TOKEN);
|
||||||
|
|
|
@ -63,7 +63,7 @@ public class EmailEventListenerProvider implements EventListenerProvider {
|
||||||
|
|
||||||
private void sendEmail(Event event) {
|
private void sendEmail(Event event) {
|
||||||
RealmModel realm = model.getRealm(event.getRealmId());
|
RealmModel realm = model.getRealm(event.getRealmId());
|
||||||
UserModel user = session.users().getUserById(event.getUserId(), realm);
|
UserModel user = session.users().getUserById(realm, event.getUserId());
|
||||||
if (user != null && user.getEmail() != null && user.isEmailVerified()) {
|
if (user != null && user.getEmail() != null && user.isEmailVerified()) {
|
||||||
try {
|
try {
|
||||||
emailTemplateProvider.setRealm(realm).setUser(user).sendEvent(event);
|
emailTemplateProvider.setRealm(realm).setUser(user).sendEvent(event);
|
||||||
|
|
|
@ -458,7 +458,7 @@ public class ExportUtils {
|
||||||
UserRepresentation userRep = ModelToRepresentation.toRepresentation(session, realm, user);
|
UserRepresentation userRep = ModelToRepresentation.toRepresentation(session, realm, user);
|
||||||
|
|
||||||
// Social links
|
// Social links
|
||||||
List<FederatedIdentityRepresentation> socialLinkReps = session.users().getFederatedIdentitiesStream(user, realm)
|
List<FederatedIdentityRepresentation> socialLinkReps = session.users().getFederatedIdentitiesStream(realm, user)
|
||||||
.map(ExportUtils::exportSocialLink).collect(Collectors.toList());
|
.map(ExportUtils::exportSocialLink).collect(Collectors.toList());
|
||||||
if (socialLinkReps.size() > 0) {
|
if (socialLinkReps.size() > 0) {
|
||||||
userRep.setFederatedIdentities(socialLinkReps);
|
userRep.setFederatedIdentities(socialLinkReps);
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class AccountFederatedIdentityBean {
|
||||||
.map(provider -> {
|
.map(provider -> {
|
||||||
String providerId = provider.getAlias();
|
String providerId = provider.getAlias();
|
||||||
|
|
||||||
FederatedIdentityModel identity = getIdentity(session.users().getFederatedIdentitiesStream(user, realm), providerId);
|
FederatedIdentityModel identity = getIdentity(session.users().getFederatedIdentitiesStream(realm, user), providerId);
|
||||||
|
|
||||||
if (identity != null) {
|
if (identity != null) {
|
||||||
availableIdentities.getAndIncrement();
|
availableIdentities.getAndIncrement();
|
||||||
|
|
|
@ -150,7 +150,7 @@ public class AuthorizationBean {
|
||||||
private boolean granted;
|
private boolean granted;
|
||||||
|
|
||||||
public RequesterBean(PermissionTicket ticket, AuthorizationProvider authorization) {
|
public RequesterBean(PermissionTicket ticket, AuthorizationProvider authorization) {
|
||||||
this.requester = authorization.getKeycloakSession().users().getUserById(ticket.getRequester(), authorization.getRealm());
|
this.requester = authorization.getKeycloakSession().users().getUserById(authorization.getRealm(), ticket.getRequester());
|
||||||
granted = ticket.isGranted();
|
granted = ticket.isGranted();
|
||||||
createdTimestamp = ticket.getCreatedTimestamp();
|
createdTimestamp = ticket.getCreatedTimestamp();
|
||||||
grantedTimestamp = ticket.getGrantedTimestamp();
|
grantedTimestamp = ticket.getGrantedTimestamp();
|
||||||
|
@ -236,7 +236,7 @@ public class AuthorizationBean {
|
||||||
RealmModel realm = authorization.getRealm();
|
RealmModel realm = authorization.getRealm();
|
||||||
resourceServer = new ResourceServerBean(realm.getClientById(resource.getResourceServer()));
|
resourceServer = new ResourceServerBean(realm.getClientById(resource.getResourceServer()));
|
||||||
this.resource = resource;
|
this.resource = resource;
|
||||||
userOwner = authorization.getKeycloakSession().users().getUserById(resource.getOwner(), realm);
|
userOwner = authorization.getKeycloakSession().users().getUserById(realm, resource.getOwner());
|
||||||
if (userOwner == null) {
|
if (userOwner == null) {
|
||||||
clientOwner = realm.getClientById(resource.getOwner());
|
clientOwner = realm.getClientById(resource.getOwner());
|
||||||
ownerName = clientOwner.getClientId();
|
ownerName = clientOwner.getClientId();
|
||||||
|
|
|
@ -54,12 +54,12 @@ public class LoginFormsUtil {
|
||||||
throw new IllegalStateException("USERNAME_EDIT_DISABLED but username not known");
|
throw new IllegalStateException("USERNAME_EDIT_DISABLED but username not known");
|
||||||
}
|
}
|
||||||
|
|
||||||
UserModel user = session.users().getUserByUsername(username, realm);
|
UserModel user = session.users().getUserByUsername(realm, username);
|
||||||
if (user == null || !user.isEnabled()) {
|
if (user == null || !user.isEnabled()) {
|
||||||
throw new IllegalStateException("User " + username + " not found or disabled");
|
throw new IllegalStateException("User " + username + " not found or disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> federatedIdentities = session.users().getFederatedIdentitiesStream(user, realm)
|
Set<String> federatedIdentities = session.users().getFederatedIdentitiesStream(realm, user)
|
||||||
.map(federatedIdentityModel -> federatedIdentityModel.getIdentityProvider())
|
.map(federatedIdentityModel -> federatedIdentityModel.getIdentityProvider())
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
|
|
@ -59,10 +59,10 @@ public class UsersPartialImport extends AbstractPartialImport<UserRepresentation
|
||||||
|
|
||||||
String userName = user.getUsername();
|
String userName = user.getUsername();
|
||||||
if (userName != null) {
|
if (userName != null) {
|
||||||
return session.users().getUserByUsername(userName, realm).getId();
|
return session.users().getUserByUsername(realm, userName).getId();
|
||||||
} else if (!realm.isDuplicateEmailsAllowed()) {
|
} else if (!realm.isDuplicateEmailsAllowed()) {
|
||||||
String email = user.getEmail();
|
String email = user.getEmail();
|
||||||
return session.users().getUserByEmail(email, realm).getId();
|
return session.users().getUserByEmail(realm, email).getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -74,12 +74,12 @@ public class UsersPartialImport extends AbstractPartialImport<UserRepresentation
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean userNameExists(RealmModel realm, KeycloakSession session, UserRepresentation user) {
|
private boolean userNameExists(RealmModel realm, KeycloakSession session, UserRepresentation user) {
|
||||||
return session.users().getUserByUsername(user.getUsername(), realm) != null;
|
return session.users().getUserByUsername(realm, user.getUsername()) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean userEmailExists(RealmModel realm, KeycloakSession session, UserRepresentation user) {
|
private boolean userEmailExists(RealmModel realm, KeycloakSession session, UserRepresentation user) {
|
||||||
return (user.getEmail() != null) && !realm.isDuplicateEmailsAllowed() &&
|
return (user.getEmail() != null) && !realm.isDuplicateEmailsAllowed() &&
|
||||||
(session.users().getUserByEmail(user.getEmail(), realm) != null);
|
(session.users().getUserByEmail(realm, user.getEmail()) != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -98,9 +98,9 @@ public class UsersPartialImport extends AbstractPartialImport<UserRepresentation
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(RealmModel realm, KeycloakSession session, UserRepresentation user) {
|
public void remove(RealmModel realm, KeycloakSession session, UserRepresentation user) {
|
||||||
UserModel userModel = session.users().getUserByUsername(user.getUsername(), realm);
|
UserModel userModel = session.users().getUserByUsername(realm, user.getUsername());
|
||||||
if (userModel == null && !realm.isDuplicateEmailsAllowed()) {
|
if (userModel == null && !realm.isDuplicateEmailsAllowed()) {
|
||||||
userModel = session.users().getUserByEmail(user.getEmail(), realm);
|
userModel = session.users().getUserByEmail(realm, user.getEmail());
|
||||||
}
|
}
|
||||||
if (userModel != null) {
|
if (userModel != null) {
|
||||||
boolean success = new UserManager(session).removeUser(realm, userModel);
|
boolean success = new UserManager(session).removeUser(realm, userModel);
|
||||||
|
|
|
@ -294,14 +294,14 @@ public class TokenManager {
|
||||||
*/
|
*/
|
||||||
public static UserModel lookupUserFromStatelessToken(KeycloakSession session, RealmModel realm, AccessToken token) {
|
public static UserModel lookupUserFromStatelessToken(KeycloakSession session, RealmModel realm, AccessToken token) {
|
||||||
// Try to lookup user based on "sub" claim. It should work for most cases with some rare exceptions (EG. OIDC "pairwise" subjects)
|
// Try to lookup user based on "sub" claim. It should work for most cases with some rare exceptions (EG. OIDC "pairwise" subjects)
|
||||||
UserModel user = session.users().getUserById(token.getSubject(), realm);
|
UserModel user = session.users().getUserById(realm, token.getSubject());
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to lookup user based on username (preferred_username claim)
|
// Fallback to lookup user based on username (preferred_username claim)
|
||||||
if (token.getPreferredUsername() != null) {
|
if (token.getPreferredUsername() != null) {
|
||||||
user = session.users().getUserByUsername(token.getPreferredUsername(), realm);
|
user = session.users().getUserByUsername(realm, token.getPreferredUsername());
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
|
@ -834,9 +834,9 @@ public class TokenEndpoint {
|
||||||
String requestedSubject = formParams.getFirst(OAuth2Constants.REQUESTED_SUBJECT);
|
String requestedSubject = formParams.getFirst(OAuth2Constants.REQUESTED_SUBJECT);
|
||||||
if (requestedSubject != null) {
|
if (requestedSubject != null) {
|
||||||
event.detail(Details.REQUESTED_SUBJECT, requestedSubject);
|
event.detail(Details.REQUESTED_SUBJECT, requestedSubject);
|
||||||
UserModel requestedUser = session.users().getUserByUsername(requestedSubject, realm);
|
UserModel requestedUser = session.users().getUserByUsername(realm, requestedSubject);
|
||||||
if (requestedUser == null) {
|
if (requestedUser == null) {
|
||||||
requestedUser = session.users().getUserById(requestedSubject, realm);
|
requestedUser = session.users().getUserById(realm, requestedSubject);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestedUser == null) {
|
if (requestedUser == null) {
|
||||||
|
@ -1135,7 +1135,7 @@ public class TokenEndpoint {
|
||||||
FederatedIdentityModel federatedIdentityModel = new FederatedIdentityModel(providerId, context.getId(),
|
FederatedIdentityModel federatedIdentityModel = new FederatedIdentityModel(providerId, context.getId(),
|
||||||
context.getUsername(), context.getToken());
|
context.getUsername(), context.getToken());
|
||||||
|
|
||||||
UserModel user = this.session.users().getUserByFederatedIdentity(federatedIdentityModel, realm);
|
UserModel user = this.session.users().getUserByFederatedIdentity(realm, federatedIdentityModel);
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
|
||||||
|
@ -1154,14 +1154,14 @@ public class TokenEndpoint {
|
||||||
username = username.trim();
|
username = username.trim();
|
||||||
context.setModelUsername(username);
|
context.setModelUsername(username);
|
||||||
if (context.getEmail() != null && !realm.isDuplicateEmailsAllowed()) {
|
if (context.getEmail() != null && !realm.isDuplicateEmailsAllowed()) {
|
||||||
UserModel existingUser = session.users().getUserByEmail(context.getEmail(), realm);
|
UserModel existingUser = session.users().getUserByEmail(realm, context.getEmail());
|
||||||
if (existingUser != null) {
|
if (existingUser != null) {
|
||||||
event.error(Errors.FEDERATED_IDENTITY_EXISTS);
|
event.error(Errors.FEDERATED_IDENTITY_EXISTS);
|
||||||
throw new CorsErrorResponseException(cors, Errors.INVALID_TOKEN, "User already exists", Response.Status.BAD_REQUEST);
|
throw new CorsErrorResponseException(cors, Errors.INVALID_TOKEN, "User already exists", Response.Status.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UserModel existingUser = session.users().getUserByUsername(username, realm);
|
UserModel existingUser = session.users().getUserByUsername(realm, username);
|
||||||
if (existingUser != null) {
|
if (existingUser != null) {
|
||||||
event.error(Errors.FEDERATED_IDENTITY_EXISTS);
|
event.error(Errors.FEDERATED_IDENTITY_EXISTS);
|
||||||
throw new CorsErrorResponseException(cors, Errors.INVALID_TOKEN, "User already exists", Response.Status.BAD_REQUEST);
|
throw new CorsErrorResponseException(cors, Errors.INVALID_TOKEN, "User already exists", Response.Status.BAD_REQUEST);
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class HttpBasicAuthenticator implements Authenticator {
|
||||||
if (usernameAndPassword != null) {
|
if (usernameAndPassword != null) {
|
||||||
final RealmModel realm = context.getRealm();
|
final RealmModel realm = context.getRealm();
|
||||||
final String username = usernameAndPassword[0];
|
final String username = usernameAndPassword[0];
|
||||||
final UserModel user = context.getSession().users().getUserByUsername(username, realm);
|
final UserModel user = context.getSession().users().getUserByUsername(realm, username);
|
||||||
|
|
||||||
// to allow success/failure logging for brute force
|
// to allow success/failure logging for brute force
|
||||||
context.getEvent().detail(Details.USERNAME, username);
|
context.getEvent().detail(Details.USERNAME, username);
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class DynamicClientRegisterContext implements ClientUpdateContext {
|
||||||
this.token = token;
|
this.token = token;
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
if (token.getSubject() != null) {
|
if (token.getSubject() != null) {
|
||||||
this.user = context.getSession().users().getUserById(token.getSubject(), realm);
|
this.user = context.getSession().users().getUserById(realm, token.getSubject());
|
||||||
}
|
}
|
||||||
if (token.getIssuedFor() != null) {
|
if (token.getIssuedFor() != null) {
|
||||||
this.client = realm.getClientByClientId(token.getIssuedFor());
|
this.client = realm.getClientByClientId(token.getIssuedFor());
|
||||||
|
|
|
@ -40,7 +40,7 @@ public class DynamicClientUpdateContext implements ClientUpdateContext {
|
||||||
this.token = token;
|
this.token = token;
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
if (token.getSubject() != null) {
|
if (token.getSubject() != null) {
|
||||||
this.user = context.getSession().users().getUserById(token.getSubject(), realm);
|
this.user = context.getSession().users().getUserById(realm, token.getSubject());
|
||||||
}
|
}
|
||||||
if (token.getIssuedFor() != null) {
|
if (token.getIssuedFor() != null) {
|
||||||
this.client = realm.getClientByClientId(token.getIssuedFor());
|
this.client = realm.getClientByClientId(token.getIssuedFor());
|
||||||
|
|
|
@ -100,7 +100,7 @@ public class ClientUpdateSourceGroupsCondition implements ClientPolicyConditionP
|
||||||
|
|
||||||
private boolean isGroupMatched(String subjectId) {
|
private boolean isGroupMatched(String subjectId) {
|
||||||
if (subjectId == null) return false;
|
if (subjectId == null) return false;
|
||||||
return isGroupsMatched(session.users().getUserById(subjectId, session.getContext().getRealm()));
|
return isGroupsMatched(session.users().getUserById(session.getContext().getRealm(), subjectId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isGroupsMatched(UserModel user) {
|
private boolean isGroupsMatched(UserModel user) {
|
||||||
|
|
|
@ -99,7 +99,7 @@ public class ClientUpdateSourceRolesCondition implements ClientPolicyConditionPr
|
||||||
|
|
||||||
private boolean isRoleMatched(String subjectId) {
|
private boolean isRoleMatched(String subjectId) {
|
||||||
if (subjectId == null) return false;
|
if (subjectId == null) return false;
|
||||||
return isRolesMatched(session.users().getUserById(subjectId, session.getContext().getRealm()));
|
return isRolesMatched(session.users().getUserById(session.getContext().getRealm(), subjectId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isRolesMatched(UserModel user) {
|
private boolean isRolesMatched(UserModel user) {
|
||||||
|
|
|
@ -291,7 +291,7 @@ public class ClientRegistrationAuth {
|
||||||
|
|
||||||
private boolean hasRoleInModel(String[] roles) {
|
private boolean hasRoleInModel(String[] roles) {
|
||||||
ClientModel roleNamespace;
|
ClientModel roleNamespace;
|
||||||
UserModel user = session.users().getUserById(jwt.getSubject(), realm);
|
UserModel user = session.users().getUserById(realm, jwt.getSubject());
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
|
||||||
logFailure(event);
|
logFailure(event);
|
||||||
|
|
||||||
String userId = event.userId;
|
String userId = event.userId;
|
||||||
UserModel user = session.users().getUserById(userId, realm);
|
UserModel user = session.users().getUserById(realm, userId);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,7 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
|
||||||
|
|
||||||
private void success(KeycloakSession session, LoginEvent event) {
|
private void success(KeycloakSession session, LoginEvent event) {
|
||||||
String userId = event.userId;
|
String userId = event.userId;
|
||||||
UserModel model = session.users().getUserById(userId, getRealmModel(session, event));
|
UserModel model = session.users().getUserById(getRealmModel(session, event), userId);
|
||||||
|
|
||||||
UserLoginFailureModel user = getUserModel(session, event);
|
UserLoginFailureModel user = getUserModel(session, event);
|
||||||
if(user == null) return;
|
if(user == null) return;
|
||||||
|
|
|
@ -485,7 +485,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||||
IdentityProviderModel identityProviderConfig = getIdentityProviderConfig(providerId);
|
IdentityProviderModel identityProviderConfig = getIdentityProviderConfig(providerId);
|
||||||
|
|
||||||
if (identityProviderConfig.isStoreToken()) {
|
if (identityProviderConfig.isStoreToken()) {
|
||||||
FederatedIdentityModel identity = this.session.users().getFederatedIdentity(authResult.getUser(), providerId, this.realmModel);
|
FederatedIdentityModel identity = this.session.users().getFederatedIdentity(this.realmModel, authResult.getUser(), providerId);
|
||||||
|
|
||||||
if (identity == null) {
|
if (identity == null) {
|
||||||
return corsResponse(badRequest("User [" + authResult.getUser().getId() + "] is not associated with identity provider [" + providerId + "]."), clientModel);
|
return corsResponse(badRequest("User [" + authResult.getUser().getId() + "] is not associated with identity provider [" + providerId + "]."), clientModel);
|
||||||
|
@ -557,12 +557,12 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||||
.detail(Details.IDENTITY_PROVIDER, providerId)
|
.detail(Details.IDENTITY_PROVIDER, providerId)
|
||||||
.detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername());
|
.detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername());
|
||||||
|
|
||||||
UserModel federatedUser = this.session.users().getUserByFederatedIdentity(federatedIdentityModel, this.realmModel);
|
UserModel federatedUser = this.session.users().getUserByFederatedIdentity(this.realmModel, federatedIdentityModel);
|
||||||
boolean shouldMigrateId = false;
|
boolean shouldMigrateId = false;
|
||||||
// try to find the user using legacy ID
|
// try to find the user using legacy ID
|
||||||
if (federatedUser == null && context.getLegacyId() != null) {
|
if (federatedUser == null && context.getLegacyId() != null) {
|
||||||
federatedIdentityModel = new FederatedIdentityModel(federatedIdentityModel, context.getLegacyId());
|
federatedIdentityModel = new FederatedIdentityModel(federatedIdentityModel, context.getLegacyId());
|
||||||
federatedUser = this.session.users().getUserByFederatedIdentity(federatedIdentityModel, this.realmModel);
|
federatedUser = this.session.users().getUserByFederatedIdentity(this.realmModel, federatedIdentityModel);
|
||||||
shouldMigrateId = true;
|
shouldMigrateId = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -962,7 +962,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||||
|
|
||||||
if (federatedUser != null) {
|
if (federatedUser != null) {
|
||||||
if (context.getIdpConfig().isStoreToken()) {
|
if (context.getIdpConfig().isStoreToken()) {
|
||||||
FederatedIdentityModel oldModel = this.session.users().getFederatedIdentity(federatedUser, context.getIdpConfig().getAlias(), this.realmModel);
|
FederatedIdentityModel oldModel = this.session.users().getFederatedIdentity(this.realmModel, federatedUser, context.getIdpConfig().getAlias());
|
||||||
if (!ObjectUtil.isEqualOrBothNull(context.getToken(), oldModel.getToken())) {
|
if (!ObjectUtil.isEqualOrBothNull(context.getToken(), oldModel.getToken())) {
|
||||||
this.session.users().updateFederatedIdentity(this.realmModel, federatedUser, newModel);
|
this.session.users().updateFederatedIdentity(this.realmModel, federatedUser, newModel);
|
||||||
if (isDebugEnabled()) {
|
if (isDebugEnabled()) {
|
||||||
|
@ -1010,7 +1010,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||||
|
|
||||||
|
|
||||||
private void updateFederatedIdentity(BrokeredIdentityContext context, UserModel federatedUser) {
|
private void updateFederatedIdentity(BrokeredIdentityContext context, UserModel federatedUser) {
|
||||||
FederatedIdentityModel federatedIdentityModel = this.session.users().getFederatedIdentity(federatedUser, context.getIdpConfig().getAlias(), this.realmModel);
|
FederatedIdentityModel federatedIdentityModel = this.session.users().getFederatedIdentity(this.realmModel, federatedUser, context.getIdpConfig().getAlias());
|
||||||
|
|
||||||
if (context.getIdpConfig().getSyncMode() == IdentityProviderSyncMode.FORCE) {
|
if (context.getIdpConfig().getSyncMode() == IdentityProviderSyncMode.FORCE) {
|
||||||
setBasicUserAttributes(context, federatedUser);
|
setBasicUserAttributes(context, federatedUser);
|
||||||
|
@ -1041,7 +1041,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||||
}
|
}
|
||||||
|
|
||||||
private void migrateFederatedIdentityId(BrokeredIdentityContext context, UserModel federatedUser) {
|
private void migrateFederatedIdentityId(BrokeredIdentityContext context, UserModel federatedUser) {
|
||||||
FederatedIdentityModel identityModel = this.session.users().getFederatedIdentity(federatedUser, context.getIdpConfig().getAlias(), this.realmModel);
|
FederatedIdentityModel identityModel = this.session.users().getFederatedIdentity(this.realmModel, federatedUser, context.getIdpConfig().getAlias());
|
||||||
FederatedIdentityModel migratedIdentityModel = new FederatedIdentityModel(identityModel, context.getId());
|
FederatedIdentityModel migratedIdentityModel = new FederatedIdentityModel(identityModel, context.getId());
|
||||||
|
|
||||||
// since ID is a partial key we need to recreate the identity
|
// since ID is a partial key we need to recreate the identity
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.keycloak.services.resources;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.common.util.Resteasy;
|
import org.keycloak.common.util.Resteasy;
|
||||||
import org.keycloak.config.ConfigProviderFactory;
|
import org.keycloak.config.ConfigProviderFactory;
|
||||||
|
@ -371,7 +370,7 @@ public class KeycloakApplication extends Application {
|
||||||
|
|
||||||
UserProvider users = session.users();
|
UserProvider users = session.users();
|
||||||
|
|
||||||
if (users.getUserByUsername(userRep.getUsername(), realm) != null) {
|
if (users.getUserByUsername(realm, userRep.getUsername()) != null) {
|
||||||
ServicesLogger.LOGGER.notCreatingExistingUser(userRep.getUsername());
|
ServicesLogger.LOGGER.notCreatingExistingUser(userRep.getUsername());
|
||||||
} else {
|
} else {
|
||||||
UserModel user = users.addUser(realm, userRep.getUsername());
|
UserModel user = users.addUser(realm, userRep.getUsername());
|
||||||
|
|
|
@ -137,7 +137,7 @@ public class LoginActionsServiceChecks {
|
||||||
* it optionally also injects the user using the given function (e.g. into session context).
|
* it optionally also injects the user using the given function (e.g. into session context).
|
||||||
*/
|
*/
|
||||||
public static void checkIsUserValid(KeycloakSession session, RealmModel realm, String userId, Consumer<UserModel> userSetter) throws VerificationException {
|
public static void checkIsUserValid(KeycloakSession session, RealmModel realm, String userId, Consumer<UserModel> userSetter) throws VerificationException {
|
||||||
UserModel user = userId == null ? null : session.users().getUserById(userId, realm);
|
UserModel user = userId == null ? null : session.users().getUserById(realm, userId);
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new ExplainedVerificationException(Errors.USER_NOT_FOUND, Messages.INVALID_USER);
|
throw new ExplainedVerificationException(Errors.USER_NOT_FOUND, Messages.INVALID_USER);
|
||||||
|
|
|
@ -709,11 +709,11 @@ public class AccountFormService extends AbstractSecuredLocalService {
|
||||||
return account.setError(Response.Status.INTERNAL_SERVER_ERROR, Messages.IDENTITY_PROVIDER_REDIRECT_ERROR).createResponse(AccountPages.FEDERATED_IDENTITY);
|
return account.setError(Response.Status.INTERNAL_SERVER_ERROR, Messages.IDENTITY_PROVIDER_REDIRECT_ERROR).createResponse(AccountPages.FEDERATED_IDENTITY);
|
||||||
}
|
}
|
||||||
case REMOVE:
|
case REMOVE:
|
||||||
FederatedIdentityModel link = session.users().getFederatedIdentity(user, providerId, realm);
|
FederatedIdentityModel link = session.users().getFederatedIdentity(realm, user, providerId);
|
||||||
if (link != null) {
|
if (link != null) {
|
||||||
|
|
||||||
// Removing last social provider is not possible if you don't have other possibility to authenticate
|
// Removing last social provider is not possible if you don't have other possibility to authenticate
|
||||||
if (session.users().getFederatedIdentitiesStream(user, realm).count() > 1 || user.getFederationLink() != null || isPasswordSet(session, realm, user)) {
|
if (session.users().getFederatedIdentitiesStream(realm, user).count() > 1 || user.getFederationLink() != null || isPasswordSet(session, realm, user)) {
|
||||||
session.users().removeFederatedIdentity(realm, user, providerId);
|
session.users().removeFederatedIdentity(realm, user, providerId);
|
||||||
|
|
||||||
logger.debugv("Social provider {0} removed successfully from user {1}", providerId, user.getUsername());
|
logger.debugv("Social provider {0} removed successfully from user {1}", providerId, user.getUsername());
|
||||||
|
@ -833,7 +833,7 @@ public class AccountFormService extends AbstractSecuredLocalService {
|
||||||
Map<String, String> filters = new HashMap<>();
|
Map<String, String> filters = new HashMap<>();
|
||||||
|
|
||||||
filters.put(PermissionTicket.RESOURCE, resource.getId());
|
filters.put(PermissionTicket.RESOURCE, resource.getId());
|
||||||
filters.put(PermissionTicket.REQUESTER, session.users().getUserByUsername(requester, realm).getId());
|
filters.put(PermissionTicket.REQUESTER, session.users().getUserByUsername(realm, requester).getId());
|
||||||
|
|
||||||
if (isRevoke) {
|
if (isRevoke) {
|
||||||
filters.put(PermissionTicket.GRANTED, Boolean.TRUE.toString());
|
filters.put(PermissionTicket.GRANTED, Boolean.TRUE.toString());
|
||||||
|
@ -909,14 +909,14 @@ public class AccountFormService extends AbstractSecuredLocalService {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String id : userIds) {
|
for (String id : userIds) {
|
||||||
UserModel user = session.users().getUserById(id, realm);
|
UserModel user = session.users().getUserById(realm, id);
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
user = session.users().getUserByUsername(id, realm);
|
user = session.users().getUserByUsername(realm, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
user = session.users().getUserByEmail(id, realm);
|
user = session.users().getUserByEmail(realm, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
|
|
@ -119,7 +119,7 @@ public class LinkedAccountsResource {
|
||||||
public SortedSet<LinkedAccountRepresentation> getLinkedAccounts(KeycloakSession session, RealmModel realm, UserModel user) {
|
public SortedSet<LinkedAccountRepresentation> getLinkedAccounts(KeycloakSession session, RealmModel realm, UserModel user) {
|
||||||
Set<String> socialIds = findSocialIds();
|
Set<String> socialIds = findSocialIds();
|
||||||
return realm.getIdentityProvidersStream().filter(IdentityProviderModel::isEnabled)
|
return realm.getIdentityProvidersStream().filter(IdentityProviderModel::isEnabled)
|
||||||
.map(provider -> toLinkedAccountRepresentation(provider, socialIds, session.users().getFederatedIdentitiesStream(user, realm)))
|
.map(provider -> toLinkedAccountRepresentation(provider, socialIds, session.users().getFederatedIdentitiesStream(realm, user)))
|
||||||
.collect(Collectors.toCollection(TreeSet::new));
|
.collect(Collectors.toCollection(TreeSet::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,13 +209,13 @@ public class LinkedAccountsResource {
|
||||||
return ErrorResponse.error(errorMessage, Response.Status.BAD_REQUEST);
|
return ErrorResponse.error(errorMessage, Response.Status.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
FederatedIdentityModel link = session.users().getFederatedIdentity(user, providerId, realm);
|
FederatedIdentityModel link = session.users().getFederatedIdentity(realm, user, providerId);
|
||||||
if (link == null) {
|
if (link == null) {
|
||||||
return ErrorResponse.error(Messages.FEDERATED_IDENTITY_NOT_ACTIVE, Response.Status.BAD_REQUEST);
|
return ErrorResponse.error(Messages.FEDERATED_IDENTITY_NOT_ACTIVE, Response.Status.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removing last social provider is not possible if you don't have other possibility to authenticate
|
// Removing last social provider is not possible if you don't have other possibility to authenticate
|
||||||
if (!(session.users().getFederatedIdentitiesStream(user, realm).count() > 1 || user.getFederationLink() != null || isPasswordSet())) {
|
if (!(session.users().getFederatedIdentitiesStream(realm, user).count() > 1 || user.getFederationLink() != null || isPasswordSet())) {
|
||||||
return ErrorResponse.error(Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER, Response.Status.BAD_REQUEST);
|
return ErrorResponse.error(Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER, Response.Status.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ public abstract class AbstractResourceService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Permission(String userId, AuthorizationProvider provider) {
|
Permission(String userId, AuthorizationProvider provider) {
|
||||||
UserModel user = provider.getKeycloakSession().users().getUserById(userId, provider.getRealm());
|
UserModel user = provider.getKeycloakSession().users().getUserById(provider.getRealm(), userId);
|
||||||
|
|
||||||
setUsername(user.getUsername());
|
setUsername(user.getUsername());
|
||||||
setFirstName(user.getFirstName());
|
setFirstName(user.getFirstName());
|
||||||
|
|
|
@ -220,10 +220,10 @@ public class ResourceService extends AbstractResourceService {
|
||||||
|
|
||||||
private UserModel getUser(String requester) {
|
private UserModel getUser(String requester) {
|
||||||
UserProvider users = provider.getKeycloakSession().users();
|
UserProvider users = provider.getKeycloakSession().users();
|
||||||
UserModel user = users.getUserByUsername(requester, provider.getRealm());
|
UserModel user = users.getUserByUsername(provider.getRealm(), requester);
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
user = users.getUserByEmail(requester, provider.getRealm());
|
user = users.getUserByEmail(provider.getRealm(), requester);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class AttackDetectionResource {
|
||||||
@NoCache
|
@NoCache
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Map<String, Object> bruteForceUserStatus(@PathParam("userId") String userId) {
|
public Map<String, Object> bruteForceUserStatus(@PathParam("userId") String userId) {
|
||||||
UserModel user = session.users().getUserById(userId, realm);
|
UserModel user = session.users().getUserById(realm, userId);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
auth.users().requireView();
|
auth.users().requireView();
|
||||||
} else {
|
} else {
|
||||||
|
@ -123,7 +123,7 @@ public class AttackDetectionResource {
|
||||||
@Path("brute-force/users/{userId}")
|
@Path("brute-force/users/{userId}")
|
||||||
@DELETE
|
@DELETE
|
||||||
public void clearBruteForceForUser(@PathParam("userId") String userId) {
|
public void clearBruteForceForUser(@PathParam("userId") String userId) {
|
||||||
UserModel user = session.users().getUserById(userId, realm);
|
UserModel user = session.users().getUserById(realm, userId);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
auth.users().requireManage();
|
auth.users().requireManage();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -160,7 +160,7 @@ public class ClientScopeEvaluateResource {
|
||||||
throw new NotFoundException("No userId provided");
|
throw new NotFoundException("No userId provided");
|
||||||
}
|
}
|
||||||
|
|
||||||
UserModel user = session.users().getUserById(userId, realm);
|
UserModel user = session.users().getUserById(realm, userId);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new NotFoundException("No user found");
|
throw new NotFoundException("No user found");
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,7 +215,7 @@ public class IdentityProviderResource {
|
||||||
|
|
||||||
private static void updateUsersAfterProviderAliasChange(Stream<UserModel> users, String oldProviderId, String newProviderId, RealmModel realm, KeycloakSession session) {
|
private static void updateUsersAfterProviderAliasChange(Stream<UserModel> users, String oldProviderId, String newProviderId, RealmModel realm, KeycloakSession session) {
|
||||||
users.forEach(user -> {
|
users.forEach(user -> {
|
||||||
FederatedIdentityModel federatedIdentity = session.users().getFederatedIdentity(user, oldProviderId, realm);
|
FederatedIdentityModel federatedIdentity = session.users().getFederatedIdentity(realm, user, oldProviderId);
|
||||||
if (federatedIdentity != null) {
|
if (federatedIdentity != null) {
|
||||||
// Remove old link first
|
// Remove old link first
|
||||||
session.users().removeFederatedIdentity(realm, user, oldProviderId);
|
session.users().removeFederatedIdentity(realm, user, oldProviderId);
|
||||||
|
|
|
@ -380,7 +380,7 @@ public class UserResource {
|
||||||
|
|
||||||
private Stream<FederatedIdentityRepresentation> getFederatedIdentities(UserModel user) {
|
private Stream<FederatedIdentityRepresentation> getFederatedIdentities(UserModel user) {
|
||||||
Set<String> idps = realm.getIdentityProvidersStream().map(IdentityProviderModel::getAlias).collect(Collectors.toSet());
|
Set<String> idps = realm.getIdentityProvidersStream().map(IdentityProviderModel::getAlias).collect(Collectors.toSet());
|
||||||
return session.users().getFederatedIdentitiesStream(user, realm)
|
return session.users().getFederatedIdentitiesStream(realm, user)
|
||||||
.filter(identity -> idps.contains(identity.getIdentityProvider()))
|
.filter(identity -> idps.contains(identity.getIdentityProvider()))
|
||||||
.map(ModelToRepresentation::toRepresentation);
|
.map(ModelToRepresentation::toRepresentation);
|
||||||
}
|
}
|
||||||
|
@ -397,7 +397,7 @@ public class UserResource {
|
||||||
@NoCache
|
@NoCache
|
||||||
public Response addFederatedIdentity(final @PathParam("provider") String provider, FederatedIdentityRepresentation rep) {
|
public Response addFederatedIdentity(final @PathParam("provider") String provider, FederatedIdentityRepresentation rep) {
|
||||||
auth.users().requireManage(user);
|
auth.users().requireManage(user);
|
||||||
if (session.users().getFederatedIdentity(user, provider, realm) != null) {
|
if (session.users().getFederatedIdentity(realm, user, provider) != null) {
|
||||||
return ErrorResponse.exists("User is already linked with provider");
|
return ErrorResponse.exists("User is already linked with provider");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,12 +133,12 @@ public class UsersResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Double-check duplicated username and email here due to federation
|
// Double-check duplicated username and email here due to federation
|
||||||
if (session.users().getUserByUsername(username, realm) != null) {
|
if (session.users().getUserByUsername(realm, username) != null) {
|
||||||
return ErrorResponse.exists("User exists with same username");
|
return ErrorResponse.exists("User exists with same username");
|
||||||
}
|
}
|
||||||
if (rep.getEmail() != null && !realm.isDuplicateEmailsAllowed()) {
|
if (rep.getEmail() != null && !realm.isDuplicateEmailsAllowed()) {
|
||||||
try {
|
try {
|
||||||
if(session.users().getUserByEmail(rep.getEmail(), realm) != null) {
|
if(session.users().getUserByEmail(realm, rep.getEmail()) != null) {
|
||||||
return ErrorResponse.exists("User exists with same email");
|
return ErrorResponse.exists("User exists with same email");
|
||||||
}
|
}
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
|
@ -192,7 +192,7 @@ public class UsersResource {
|
||||||
*/
|
*/
|
||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
public UserResource user(final @PathParam("id") String id) {
|
public UserResource user(final @PathParam("id") String id) {
|
||||||
UserModel user = session.users().getUserById(id, realm);
|
UserModel user = session.users().getUserById(realm, id);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
// we do this to make sure somebody can't phish ids
|
// we do this to make sure somebody can't phish ids
|
||||||
if (auth.users().canQuery()) throw new NotFoundException("User not found");
|
if (auth.users().canQuery()) throw new NotFoundException("User not found");
|
||||||
|
@ -251,7 +251,7 @@ public class UsersResource {
|
||||||
if (search != null) {
|
if (search != null) {
|
||||||
if (search.startsWith(SEARCH_ID_PARAMETER)) {
|
if (search.startsWith(SEARCH_ID_PARAMETER)) {
|
||||||
UserModel userModel =
|
UserModel userModel =
|
||||||
session.users().getUserById(search.substring(SEARCH_ID_PARAMETER.length()).trim(), realm);
|
session.users().getUserById(realm, search.substring(SEARCH_ID_PARAMETER.length()).trim());
|
||||||
if (userModel != null) {
|
if (userModel != null) {
|
||||||
userModels = Stream.of(userModel);
|
userModels = Stream.of(userModel);
|
||||||
}
|
}
|
||||||
|
@ -341,12 +341,12 @@ public class UsersResource {
|
||||||
|
|
||||||
if (search != null) {
|
if (search != null) {
|
||||||
if (search.startsWith(SEARCH_ID_PARAMETER)) {
|
if (search.startsWith(SEARCH_ID_PARAMETER)) {
|
||||||
UserModel userModel = session.users().getUserById(search.substring(SEARCH_ID_PARAMETER.length()).trim(), realm);
|
UserModel userModel = session.users().getUserById(realm, search.substring(SEARCH_ID_PARAMETER.length()).trim());
|
||||||
return userModel != null && userPermissionEvaluator.canView(userModel) ? 1 : 0;
|
return userModel != null && userPermissionEvaluator.canView(userModel) ? 1 : 0;
|
||||||
} else if (userPermissionEvaluator.canView()) {
|
} else if (userPermissionEvaluator.canView()) {
|
||||||
return session.users().getUsersCount(search.trim(), realm);
|
return session.users().getUsersCount(realm, search.trim());
|
||||||
} else {
|
} else {
|
||||||
return session.users().getUsersCount(search.trim(), realm, auth.groups().getGroupsWithViewPermission());
|
return session.users().getUsersCount(realm, search.trim(), auth.groups().getGroupsWithViewPermission());
|
||||||
}
|
}
|
||||||
} else if (last != null || first != null || email != null || username != null || emailVerified != null) {
|
} else if (last != null || first != null || email != null || username != null || emailVerified != null) {
|
||||||
Map<String, String> parameters = new HashMap<>();
|
Map<String, String> parameters = new HashMap<>();
|
||||||
|
@ -366,9 +366,9 @@ public class UsersResource {
|
||||||
parameters.put(UserModel.EMAIL_VERIFIED, emailVerified.toString());
|
parameters.put(UserModel.EMAIL_VERIFIED, emailVerified.toString());
|
||||||
}
|
}
|
||||||
if (userPermissionEvaluator.canView()) {
|
if (userPermissionEvaluator.canView()) {
|
||||||
return session.users().getUsersCount(parameters, realm);
|
return session.users().getUsersCount(realm, parameters);
|
||||||
} else {
|
} else {
|
||||||
return session.users().getUsersCount(parameters, realm, auth.groups().getGroupsWithViewPermission());
|
return session.users().getUsersCount(realm, parameters, auth.groups().getGroupsWithViewPermission());
|
||||||
}
|
}
|
||||||
} else if (userPermissionEvaluator.canView()) {
|
} else if (userPermissionEvaluator.canView()) {
|
||||||
return session.users().getUsersCount(realm);
|
return session.users().getUsersCount(realm);
|
||||||
|
@ -388,7 +388,7 @@ public class UsersResource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<UserModel> userModels = session.users().searchForUserStream(attributes, realm, firstResult, maxResults);
|
Stream<UserModel> userModels = session.users().searchForUserStream(realm, attributes, firstResult, maxResults);
|
||||||
return toRepresentation(realm, usersEvaluator, briefRepresentation, userModels);
|
return toRepresentation(realm, usersEvaluator, briefRepresentation, userModels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ public class TwitterIdentityProvider extends AbstractIdentityProvider<OAuth2Iden
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Response exchangeStoredToken(UriInfo uriInfo, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject) {
|
protected Response exchangeStoredToken(UriInfo uriInfo, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject) {
|
||||||
FederatedIdentityModel model = session.users().getFederatedIdentity(tokenSubject, getConfig().getAlias(), authorizedClient.getRealm());
|
FederatedIdentityModel model = session.users().getFederatedIdentity(authorizedClient.getRealm(), tokenSubject, getConfig().getAlias());
|
||||||
if (model == null || model.getToken() == null) {
|
if (model == null || model.getToken() == null) {
|
||||||
return exchangeNotLinked(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
|
return exchangeNotLinked(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ import java.util.function.Predicate;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static org.keycloak.models.utils.KeycloakModelUtils.runJobInTransaction;
|
import static org.keycloak.models.utils.KeycloakModelUtils.runJobInTransaction;
|
||||||
|
import static org.keycloak.utils.StreamsUtil.paginatedStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -136,7 +137,7 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
runJobInTransaction(session.getKeycloakSessionFactory(), session -> {
|
runJobInTransaction(session.getKeycloakSessionFactory(), session -> {
|
||||||
RealmModel realmModel = session.realms().getRealm(realm.getId());
|
RealmModel realmModel = session.realms().getRealm(realm.getId());
|
||||||
if (realmModel == null) return;
|
if (realmModel == null) return;
|
||||||
UserModel deletedUser = session.userLocalStorage().getUserById(userId, realmModel);
|
UserModel deletedUser = session.userLocalStorage().getUserById(realmModel, userId);
|
||||||
if (deletedUser != null) {
|
if (deletedUser != null) {
|
||||||
try {
|
try {
|
||||||
new UserManager(session).removeUser(realmModel, deletedUser, session.userLocalStorage());
|
new UserManager(session).removeUser(realmModel, deletedUser, session.userLocalStorage());
|
||||||
|
@ -161,10 +162,8 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
Stream<UserModel> query(Object provider);
|
Stream<UserModel> query(Object provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Stream<UserModel> query(PaginatedQuery pagedQuery, RealmModel realm, int firstResult, int maxResults) {
|
protected Stream<UserModel> query(PaginatedQuery pagedQuery, RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
if (maxResults == 0) return Stream.empty();
|
if (maxResults != null && maxResults == 0) return Stream.empty();
|
||||||
if (firstResult < 0) firstResult = 0;
|
|
||||||
if (maxResults < 0) maxResults = Integer.MAX_VALUE - 1;
|
|
||||||
|
|
||||||
Stream<Object> providersStream = Stream.concat(Stream.of((Object) localStorage()), getEnabledStorageProviders(realm, UserQueryProvider.class));
|
Stream<Object> providersStream = Stream.concat(Stream.of((Object) localStorage()), getEnabledStorageProviders(realm, UserQueryProvider.class));
|
||||||
|
|
||||||
|
@ -173,9 +172,7 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
providersStream = Stream.concat(providersStream, Stream.of(federatedStorageProvider));
|
providersStream = Stream.concat(providersStream, Stream.of(federatedStorageProvider));
|
||||||
}
|
}
|
||||||
|
|
||||||
return providersStream.flatMap(pagedQuery::query)
|
return paginatedStream(providersStream.flatMap(pagedQuery::query), firstResult, maxResults);
|
||||||
.skip(firstResult)
|
|
||||||
.limit(maxResults);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -232,33 +229,33 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
{@link UserLookupProvider} methods implementations start here */
|
{@link UserLookupProvider} methods implementations start here */
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
public UserModel getUserById(RealmModel realm, String id) {
|
||||||
StorageId storageId = new StorageId(id);
|
StorageId storageId = new StorageId(id);
|
||||||
if (storageId.getProviderId() == null) {
|
if (storageId.getProviderId() == null) {
|
||||||
UserModel user = localStorage().getUserById(id, realm);
|
UserModel user = localStorage().getUserById(realm, id);
|
||||||
return importValidation(realm, user);
|
return importValidation(realm, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserLookupProvider provider = getStorageProviderInstance(realm, storageId.getProviderId(), UserLookupProvider.class);
|
UserLookupProvider provider = getStorageProviderInstance(realm, storageId.getProviderId(), UserLookupProvider.class);
|
||||||
if (provider == null) return null;
|
if (provider == null) return null;
|
||||||
|
|
||||||
return provider.getUserById(id, realm);
|
return provider.getUserById(realm, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
public UserModel getUserByUsername(RealmModel realm, String username) {
|
||||||
UserModel user = localStorage().getUserByUsername(username, realm);
|
UserModel user = localStorage().getUserByUsername(realm, username);
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
return importValidation(realm, user);
|
return importValidation(realm, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapEnabledStorageProvidersWithTimeout(realm, UserLookupProvider.class,
|
return mapEnabledStorageProvidersWithTimeout(realm, UserLookupProvider.class,
|
||||||
provider -> provider.getUserByUsername(username, realm)).findFirst().orElse(null);
|
provider -> provider.getUserByUsername(realm, username)).findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
public UserModel getUserByEmail(RealmModel realm, String email) {
|
||||||
UserModel user = localStorage().getUserByEmail(email, realm);
|
UserModel user = localStorage().getUserByEmail(realm, email);
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
user = importValidation(realm, user);
|
user = importValidation(realm, user);
|
||||||
// Case when email was changed directly in the userStorage and doesn't correspond anymore to the email from local DB
|
// Case when email was changed directly in the userStorage and doesn't correspond anymore to the email from local DB
|
||||||
|
@ -268,17 +265,12 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapEnabledStorageProvidersWithTimeout(realm, UserLookupProvider.class,
|
return mapEnabledStorageProvidersWithTimeout(realm, UserLookupProvider.class,
|
||||||
provider -> provider.getUserByEmail(email, realm)).findFirst().orElse(null);
|
provider -> provider.getUserByEmail(realm, email)).findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@link UserLookupProvider} methods implementations end here
|
/** {@link UserLookupProvider} methods implementations end here
|
||||||
{@link UserQueryProvider} methods implementation start here */
|
{@link UserQueryProvider} methods implementation start here */
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
|
|
||||||
return getGroupMembersStream(realm, group, -1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getGroupMembersStream(final RealmModel realm, final GroupModel group, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> getGroupMembersStream(final RealmModel realm, final GroupModel group, Integer firstResult, Integer maxResults) {
|
||||||
Stream<UserModel> results = query((provider) -> {
|
Stream<UserModel> results = query((provider) -> {
|
||||||
|
@ -287,7 +279,7 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
|
|
||||||
} else if (provider instanceof UserFederatedStorageProvider) {
|
} else if (provider instanceof UserFederatedStorageProvider) {
|
||||||
return ((UserFederatedStorageProvider)provider).getMembershipStream(realm, group, -1, -1).
|
return ((UserFederatedStorageProvider)provider).getMembershipStream(realm, group, -1, -1).
|
||||||
map(id -> getUserById(id, realm));
|
map(id -> getUserById(realm, id));
|
||||||
}
|
}
|
||||||
return Stream.empty();
|
return Stream.empty();
|
||||||
}, realm, firstResult, maxResults);
|
}, realm, firstResult, maxResults);
|
||||||
|
@ -295,11 +287,6 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
return importValidation(realm, results);
|
return importValidation(realm, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role) {
|
|
||||||
return getRoleMembersStream(realm, role, -1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getRoleMembersStream(final RealmModel realm, final RoleModel role, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> getRoleMembersStream(final RealmModel realm, final RoleModel role, Integer firstResult, Integer maxResults) {
|
||||||
Stream<UserModel> results = query((provider) -> {
|
Stream<UserModel> results = query((provider) -> {
|
||||||
|
@ -314,19 +301,14 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm) {
|
public Stream<UserModel> getUsersStream(RealmModel realm) {
|
||||||
return getUsersStream(realm, false);
|
return getUsersStream(realm, null, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
|
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
return getUsersStream(realm, firstResult, maxResults, false);
|
return getUsersStream(realm, firstResult, maxResults, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts) {
|
|
||||||
return getUsersStream(realm, 0, Integer.MAX_VALUE - 1, includeServiceAccounts);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getUsersStream(final RealmModel realm, Integer firstResult, Integer maxResults, final boolean includeServiceAccounts) {
|
public Stream<UserModel> getUsersStream(final RealmModel realm, Integer firstResult, Integer maxResults, final boolean includeServiceAccounts) {
|
||||||
Stream<UserModel> results = query((provider) -> {
|
Stream<UserModel> results = query((provider) -> {
|
||||||
|
@ -362,35 +344,30 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // TODO: missing storageProviders count?
|
@Override // TODO: missing storageProviders count?
|
||||||
public int getUsersCount(String search, RealmModel realm) {
|
public int getUsersCount(RealmModel realm, String search) {
|
||||||
return localStorage().getUsersCount(search, realm);
|
return localStorage().getUsersCount(realm, search);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // TODO: missing storageProviders count?
|
@Override // TODO: missing storageProviders count?
|
||||||
public int getUsersCount(String search, RealmModel realm, Set<String> groupIds) {
|
public int getUsersCount(RealmModel realm, String search, Set<String> groupIds) {
|
||||||
return localStorage().getUsersCount(search, realm, groupIds);
|
return localStorage().getUsersCount(realm, search, groupIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // TODO: missing storageProviders count?
|
@Override // TODO: missing storageProviders count?
|
||||||
public int getUsersCount(Map<String, String> params, RealmModel realm) {
|
public int getUsersCount(RealmModel realm, Map<String, String> params) {
|
||||||
return localStorage().getUsersCount(params, realm);
|
return localStorage().getUsersCount(realm, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // TODO: missing storageProviders count?
|
@Override // TODO: missing storageProviders count?
|
||||||
public int getUsersCount(Map<String, String> params, RealmModel realm, Set<String> groupIds) {
|
public int getUsersCount(RealmModel realm, Map<String, String> params, Set<String> groupIds) {
|
||||||
return localStorage().getUsersCount(params, realm, groupIds);
|
return localStorage().getUsersCount(realm, params, groupIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
||||||
return searchForUserStream(search, realm, 0, Integer.MAX_VALUE - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
|
|
||||||
Stream<UserModel> results = query((provider) -> {
|
Stream<UserModel> results = query((provider) -> {
|
||||||
if (provider instanceof UserQueryProvider) {
|
if (provider instanceof UserQueryProvider) {
|
||||||
return ((UserQueryProvider)provider).searchForUserStream(search, realm);
|
return ((UserQueryProvider)provider).searchForUserStream(realm, search);
|
||||||
}
|
}
|
||||||
return Stream.empty();
|
return Stream.empty();
|
||||||
}, realm, firstResult, maxResults);
|
}, realm, firstResult, maxResults);
|
||||||
|
@ -398,18 +375,13 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes, Integer firstResult, Integer maxResults) {
|
||||||
return searchForUserStream(attributes, realm, 0, Integer.MAX_VALUE - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm, Integer firstResult, Integer maxResults) {
|
|
||||||
Stream<UserModel> results = query((provider) -> {
|
Stream<UserModel> results = query((provider) -> {
|
||||||
if (provider instanceof UserQueryProvider) {
|
if (provider instanceof UserQueryProvider) {
|
||||||
if (attributes.containsKey(UserModel.SEARCH)) {
|
if (attributes.containsKey(UserModel.SEARCH)) {
|
||||||
return ((UserQueryProvider)provider).searchForUserStream(attributes.get(UserModel.SEARCH), realm);
|
return ((UserQueryProvider)provider).searchForUserStream(realm, attributes.get(UserModel.SEARCH));
|
||||||
} else {
|
} else {
|
||||||
return ((UserQueryProvider)provider).searchForUserStream(attributes, realm);
|
return ((UserQueryProvider)provider).searchForUserStream(realm, attributes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Stream.empty();
|
return Stream.empty();
|
||||||
|
@ -419,18 +391,18 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
|
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
|
||||||
Stream<UserModel> results = query((provider) -> {
|
Stream<UserModel> results = query((provider) -> {
|
||||||
if (provider instanceof UserQueryProvider) {
|
if (provider instanceof UserQueryProvider) {
|
||||||
return ((UserQueryProvider)provider).searchForUserByUserAttributeStream(attrName, attrValue, realm);
|
return ((UserQueryProvider)provider).searchForUserByUserAttributeStream(realm, attrName, attrValue);
|
||||||
} else if (provider instanceof UserFederatedStorageProvider) {
|
} else if (provider instanceof UserFederatedStorageProvider) {
|
||||||
return ((UserFederatedStorageProvider)provider).getUsersByUserAttributeStream(realm, attrName, attrValue)
|
return ((UserFederatedStorageProvider)provider).getUsersByUserAttributeStream(realm, attrName, attrValue)
|
||||||
.map(id -> getUserById(id, realm))
|
.map(id -> getUserById(realm, id))
|
||||||
.filter(Objects::nonNull);
|
.filter(Objects::nonNull);
|
||||||
|
|
||||||
}
|
}
|
||||||
return Stream.empty();
|
return Stream.empty();
|
||||||
}, realm,0, Integer.MAX_VALUE - 1);
|
}, realm,null, null);
|
||||||
|
|
||||||
// removeDuplicates method may cause concurrent issues, it should not be used on parallel streams
|
// removeDuplicates method may cause concurrent issues, it should not be used on parallel streams
|
||||||
results = removeDuplicates(results);
|
results = removeDuplicates(results);
|
||||||
|
@ -594,14 +566,14 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm) {
|
public UserModel getUserByFederatedIdentity(RealmModel realm, FederatedIdentityModel socialLink) {
|
||||||
UserModel user = localStorage().getUserByFederatedIdentity(socialLink, realm);
|
UserModel user = localStorage().getUserByFederatedIdentity(realm, socialLink);
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
return importValidation(realm, user);
|
return importValidation(realm, user);
|
||||||
}
|
}
|
||||||
if (getFederatedStorage() == null) return null;
|
if (getFederatedStorage() == null) return null;
|
||||||
String id = getFederatedStorage().getUserByFederatedIdentity(socialLink, realm);
|
String id = getFederatedStorage().getUserByFederatedIdentity(socialLink, realm);
|
||||||
if (id != null) return getUserById(id, realm);
|
if (id != null) return getUserById(realm, id);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,20 +583,20 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm) {
|
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel realm, UserModel user) {
|
||||||
if (user == null) throw new IllegalStateException("Federated user no longer valid");
|
if (user == null) throw new IllegalStateException("Federated user no longer valid");
|
||||||
Stream<FederatedIdentityModel> stream = StorageId.isLocalStorage(user) ?
|
Stream<FederatedIdentityModel> stream = StorageId.isLocalStorage(user) ?
|
||||||
localStorage().getFederatedIdentitiesStream(user, realm) : Stream.empty();
|
localStorage().getFederatedIdentitiesStream(realm, user) : Stream.empty();
|
||||||
if (getFederatedStorage() != null)
|
if (getFederatedStorage() != null)
|
||||||
stream = Stream.concat(stream, getFederatedStorage().getFederatedIdentitiesStream(user.getId(), realm));
|
stream = Stream.concat(stream, getFederatedStorage().getFederatedIdentitiesStream(user.getId(), realm));
|
||||||
return stream.distinct();
|
return stream.distinct();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm) {
|
public FederatedIdentityModel getFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
|
||||||
if (user == null) throw new IllegalStateException("Federated user no longer valid");
|
if (user == null) throw new IllegalStateException("Federated user no longer valid");
|
||||||
if (StorageId.isLocalStorage(user)) {
|
if (StorageId.isLocalStorage(user)) {
|
||||||
FederatedIdentityModel model = localStorage().getFederatedIdentity(user, socialProvider, realm);
|
FederatedIdentityModel model = localStorage().getFederatedIdentity(realm, user, socialProvider);
|
||||||
if (model != null) return model;
|
if (model != null) return model;
|
||||||
}
|
}
|
||||||
if (getFederatedStorage() != null) return getFederatedStorage().getFederatedIdentity(user.getId(), socialProvider, realm);
|
if (getFederatedStorage() != null) return getFederatedStorage().getFederatedIdentity(user.getId(), socialProvider, realm);
|
||||||
|
|
|
@ -95,7 +95,7 @@ public class LegacyUserProfileProvider implements UserProfileProvider {
|
||||||
builder.addAttributeValidator().forAttribute(UserModel.USERNAME)
|
builder.addAttributeValidator().forAttribute(UserModel.USERNAME)
|
||||||
.addSingleAttributeValueValidationFunction(Messages.MISSING_USERNAME, StaticValidators.isBlank())
|
.addSingleAttributeValueValidationFunction(Messages.MISSING_USERNAME, StaticValidators.isBlank())
|
||||||
.addSingleAttributeValueValidationFunction(Messages.USERNAME_EXISTS,
|
.addSingleAttributeValueValidationFunction(Messages.USERNAME_EXISTS,
|
||||||
(value, o) -> session.users().getUserByUsername(value, realm) == null)
|
(value, o) -> session.users().getUserByUsername(realm, value) == null)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class StaticValidators {
|
||||||
if (Validation.isBlank(value)) return true;
|
if (Validation.isBlank(value)) return true;
|
||||||
return !(context.getCurrentProfile() != null
|
return !(context.getCurrentProfile() != null
|
||||||
&& !value.equals(context.getCurrentProfile().getAttributes().getFirstAttribute(UserModel.USERNAME))
|
&& !value.equals(context.getCurrentProfile().getAttributes().getFirstAttribute(UserModel.USERNAME))
|
||||||
&& session.users().getUserByUsername(value, session.getContext().getRealm()) != null);
|
&& session.users().getUserByUsername(session.getContext().getRealm(), value) != null);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ public class StaticValidators {
|
||||||
if (Validation.isBlank(value)) return true;
|
if (Validation.isBlank(value)) return true;
|
||||||
RealmModel realm = session.getContext().getRealm();
|
RealmModel realm = session.getContext().getRealm();
|
||||||
if (!realm.isDuplicateEmailsAllowed()) {
|
if (!realm.isDuplicateEmailsAllowed()) {
|
||||||
UserModel userByEmail = session.users().getUserByEmail(value, realm);
|
UserModel userByEmail = session.users().getUserByEmail(realm, value);
|
||||||
return !(realm.isRegistrationEmailAsUsername() && userByEmail != null && context.getCurrentProfile() != null && !userByEmail.getId().equals(context.getCurrentProfile().getId()));
|
return !(realm.isRegistrationEmailAsUsername() && userByEmail != null && context.getCurrentProfile() != null && !userByEmail.getId().equals(context.getCurrentProfile().getId()));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -92,7 +92,7 @@ public class StaticValidators {
|
||||||
if (Validation.isBlank(value)) return true;
|
if (Validation.isBlank(value)) return true;
|
||||||
RealmModel realm = session.getContext().getRealm();
|
RealmModel realm = session.getContext().getRealm();
|
||||||
if (!realm.isDuplicateEmailsAllowed()) {
|
if (!realm.isDuplicateEmailsAllowed()) {
|
||||||
UserModel userByEmail = session.users().getUserByEmail(value, realm);
|
UserModel userByEmail = session.users().getUserByEmail(realm, value);
|
||||||
// check for duplicated email
|
// check for duplicated email
|
||||||
return !(userByEmail != null && (context.getCurrentProfile() == null || !userByEmail.getId().equals(context.getCurrentProfile().getId())));
|
return !(userByEmail != null && (context.getCurrentProfile() == null || !userByEmail.getId().equals(context.getCurrentProfile().getId())));
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ public class StaticValidators {
|
||||||
return (value, context) ->
|
return (value, context) ->
|
||||||
!(value != null
|
!(value != null
|
||||||
&& !session.getContext().getRealm().isDuplicateEmailsAllowed()
|
&& !session.getContext().getRealm().isDuplicateEmailsAllowed()
|
||||||
&& session.users().getUserByEmail(value, session.getContext().getRealm()) != null);
|
&& session.users().getUserByEmail(session.getContext().getRealm(), value) != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BiFunction<List<String>, UserProfileContext, Boolean> isAttributeUnchanged(String attributeName) {
|
public static BiFunction<List<String>, UserProfileContext, Boolean> isAttributeUnchanged(String attributeName) {
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class ExpectedParamAuthenticator implements Authenticator {
|
||||||
if (loggedUser == null) {
|
if (loggedUser == null) {
|
||||||
logger.info("Successfully authenticated, but don't set any authenticated user");
|
logger.info("Successfully authenticated, but don't set any authenticated user");
|
||||||
} else {
|
} else {
|
||||||
UserModel user = context.getSession().users().getUserByUsername(loggedUser, context.getRealm());
|
UserModel user = context.getSession().users().getUserByUsername(context.getRealm(), loggedUser);
|
||||||
logger.info("Successfully authenticated as user " + user.getUsername());
|
logger.info("Successfully authenticated as user " + user.getUsername());
|
||||||
context.setUser(user);
|
context.setUser(user);
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,7 +342,7 @@ public class BackwardsCompatibilityUserStorage implements UserLookupProvider, Us
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
|
public List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
|
||||||
UserModel user = getUserByUsername(search, realm);
|
UserModel user = getUserByUsername(realm, search);
|
||||||
return user == null ? Collections.emptyList() : Arrays.asList(user);
|
return user == null ? Collections.emptyList() : Arrays.asList(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,10 @@ package org.keycloak.testsuite.federation;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.credential.CredentialInput;
|
import org.keycloak.credential.CredentialInput;
|
||||||
import org.keycloak.credential.CredentialInputValidator;
|
import org.keycloak.credential.CredentialInputValidator;
|
||||||
import org.keycloak.credential.CredentialModel;
|
|
||||||
import org.keycloak.models.GroupModel;
|
import org.keycloak.models.GroupModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.credential.OTPCredentialModel;
|
import org.keycloak.models.credential.OTPCredentialModel;
|
||||||
import org.keycloak.models.credential.PasswordCredentialModel;
|
import org.keycloak.models.credential.PasswordCredentialModel;
|
||||||
|
@ -34,7 +32,6 @@ import org.keycloak.storage.user.UserLookupProvider;
|
||||||
import org.keycloak.storage.user.UserRegistrationProvider;
|
import org.keycloak.storage.user.UserRegistrationProvider;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -44,7 +41,7 @@ import java.util.Set;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class DummyUserFederationProvider implements UserStorageProvider,
|
public class DummyUserFederationProvider implements UserStorageProvider,
|
||||||
UserLookupProvider,
|
UserLookupProvider.Streams,
|
||||||
UserRegistrationProvider,
|
UserRegistrationProvider,
|
||||||
CredentialInputValidator {
|
CredentialInputValidator {
|
||||||
|
|
||||||
|
@ -83,17 +80,17 @@ public class DummyUserFederationProvider implements UserStorageProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
public UserModel getUserById(RealmModel realm, String id) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
public UserModel getUserByUsername(RealmModel realm, String username) {
|
||||||
return users.get(username);
|
return users.get(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
public UserModel getUserByEmail(RealmModel realm, String email) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ import java.util.stream.Stream;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class FailableHardcodedStorageProvider implements UserStorageProvider, UserLookupProvider, UserQueryProvider.Streams,
|
public class FailableHardcodedStorageProvider implements UserStorageProvider, UserLookupProvider.Streams, UserQueryProvider.Streams,
|
||||||
ImportedUserValidation, CredentialInputUpdater.Streams, CredentialInputValidator {
|
ImportedUserValidation, CredentialInputUpdater.Streams, CredentialInputValidator {
|
||||||
|
|
||||||
public static String username = "billb";
|
public static String username = "billb";
|
||||||
|
@ -172,16 +172,16 @@ public class FailableHardcodedStorageProvider implements UserStorageProvider, Us
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
public UserModel getUserById(RealmModel realm, String id) {
|
||||||
checkForceFail();
|
checkForceFail();
|
||||||
throw new RuntimeException("THIS IMPORTS SHOULD NEVER BE CALLED");
|
throw new RuntimeException("THIS IMPORTS SHOULD NEVER BE CALLED");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByUsername(String uname, RealmModel realm) {
|
public UserModel getUserByUsername(RealmModel realm, String uname) {
|
||||||
checkForceFail();
|
checkForceFail();
|
||||||
if (!username.equals(uname)) return null;
|
if (!username.equals(uname)) return null;
|
||||||
UserModel local = session.userLocalStorage().getUserByUsername(uname, realm);
|
UserModel local = session.userLocalStorage().getUserByUsername(realm, uname);
|
||||||
if (local != null && !model.getId().equals(local.getFederationLink())) {
|
if (local != null && !model.getId().equals(local.getFederationLink())) {
|
||||||
throw new RuntimeException("local storage has wrong federation link");
|
throw new RuntimeException("local storage has wrong federation link");
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ public class FailableHardcodedStorageProvider implements UserStorageProvider, Us
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
public UserModel getUserByEmail(RealmModel realm, String email) {
|
||||||
checkForceFail();
|
checkForceFail();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -223,46 +223,46 @@ public class FailableHardcodedStorageProvider implements UserStorageProvider, Us
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm) {
|
public Stream<UserModel> getUsersStream(RealmModel realm) {
|
||||||
checkForceFail();
|
checkForceFail();
|
||||||
UserModel model = getUserByUsername(username, realm);
|
UserModel model = getUserByUsername(realm, username);
|
||||||
return model != null ? Stream.of(model) : Stream.empty();
|
return model != null ? Stream.of(model) : Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
|
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
checkForceFail();
|
checkForceFail();
|
||||||
UserModel model = getUserByUsername(username, realm);
|
UserModel model = getUserByUsername(realm, username);
|
||||||
return model != null ? Stream.of(model) : Stream.empty();
|
return model != null ? Stream.of(model) : Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search) {
|
||||||
checkForceFail();
|
checkForceFail();
|
||||||
if (!search.equals(username)) return Stream.empty();
|
if (!search.equals(username)) return Stream.empty();
|
||||||
UserModel model = getUserByUsername(username, realm);
|
UserModel model = getUserByUsername(realm, username);
|
||||||
return model != null ? Stream.of(model) : Stream.empty();
|
return model != null ? Stream.of(model) : Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
||||||
checkForceFail();
|
checkForceFail();
|
||||||
if (!search.equals(username)) return Stream.empty();
|
if (!search.equals(username)) return Stream.empty();
|
||||||
UserModel model = getUserByUsername(username, realm);
|
UserModel model = getUserByUsername(realm, username);
|
||||||
return model != null ? Stream.of(model) : Stream.empty();
|
return model != null ? Stream.of(model) : Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params) {
|
||||||
checkForceFail();
|
checkForceFail();
|
||||||
if (!username.equals(params.get("username")))return Stream.empty();
|
if (!username.equals(params.get("username")))return Stream.empty();
|
||||||
UserModel model = getUserByUsername(username, realm);
|
UserModel model = getUserByUsername(realm, username);
|
||||||
return model != null ? Stream.of(model) : Stream.empty();
|
return model != null ? Stream.of(model) : Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params, Integer firstResult, Integer maxResults) {
|
||||||
checkForceFail();
|
checkForceFail();
|
||||||
if (!username.equals(params.get("username")))return Stream.empty();
|
if (!username.equals(params.get("username")))return Stream.empty();
|
||||||
UserModel model = getUserByUsername(username, realm);
|
UserModel model = getUserByUsername(realm, username);
|
||||||
return model != null ? Stream.of(model) : Stream.empty();
|
return model != null ? Stream.of(model) : Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ public class FailableHardcodedStorageProvider implements UserStorageProvider, Us
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
|
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
|
||||||
checkForceFail();
|
checkForceFail();
|
||||||
return Stream.empty();
|
return Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ import java.util.stream.Collectors;
|
||||||
*/
|
*/
|
||||||
public class PassThroughFederatedUserStorageProvider implements
|
public class PassThroughFederatedUserStorageProvider implements
|
||||||
UserStorageProvider,
|
UserStorageProvider,
|
||||||
UserLookupProvider,
|
UserLookupProvider.Streams,
|
||||||
CredentialInputValidator,
|
CredentialInputValidator,
|
||||||
CredentialInputUpdater
|
CredentialInputUpdater
|
||||||
{
|
{
|
||||||
|
@ -130,20 +130,20 @@ public class PassThroughFederatedUserStorageProvider implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
public UserModel getUserById(RealmModel realm, String id) {
|
||||||
if (!StorageId.externalId(id).equals(PASSTHROUGH_USERNAME)) return null;
|
if (!StorageId.externalId(id).equals(PASSTHROUGH_USERNAME)) return null;
|
||||||
return getUserModel(realm);
|
return getUserModel(realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
public UserModel getUserByUsername(RealmModel realm, String username) {
|
||||||
if (!PASSTHROUGH_USERNAME.equals(username)) return null;
|
if (!PASSTHROUGH_USERNAME.equals(username)) return null;
|
||||||
|
|
||||||
return getUserModel(realm);
|
return getUserModel(realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
public UserModel getUserByEmail(RealmModel realm, String email) {
|
||||||
Optional<StorageId> result = session.userFederatedStorage()
|
Optional<StorageId> result = session.userFederatedStorage()
|
||||||
.getUsersByUserAttributeStream(realm, AbstractUserAdapterFederatedStorage.EMAIL_ATTRIBUTE, email)
|
.getUsersByUserAttributeStream(realm, AbstractUserAdapterFederatedStorage.EMAIL_ATTRIBUTE, email)
|
||||||
.map(StorageId::new)
|
.map(StorageId::new)
|
||||||
|
|
|
@ -48,12 +48,13 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import static org.keycloak.storage.UserStorageProviderModel.IMPORT_ENABLED;
|
import static org.keycloak.storage.UserStorageProviderModel.IMPORT_ENABLED;
|
||||||
|
import static org.keycloak.utils.StreamsUtil.paginatedStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class UserMapStorage implements UserLookupProvider, UserStorageProvider, UserRegistrationProvider, CredentialInputUpdater.Streams,
|
public class UserMapStorage implements UserLookupProvider.Streams, UserStorageProvider, UserRegistrationProvider, CredentialInputUpdater.Streams,
|
||||||
CredentialInputValidator, UserGroupMembershipFederatedStorage.Streams, UserQueryProvider.Streams, ImportedUserValidation {
|
CredentialInputValidator, UserGroupMembershipFederatedStorage.Streams, UserQueryProvider.Streams, ImportedUserValidation {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(UserMapStorage.class);
|
private static final Logger log = Logger.getLogger(UserMapStorage.class);
|
||||||
|
@ -91,7 +92,7 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
public UserModel getUserById(RealmModel realm, String id) {
|
||||||
StorageId storageId = new StorageId(id);
|
StorageId storageId = new StorageId(id);
|
||||||
final String username = storageId.getExternalId();
|
final String username = storageId.getExternalId();
|
||||||
if (!userPasswords.containsKey(translateUserName(username))) {
|
if (!userPasswords.containsKey(translateUserName(username))) {
|
||||||
|
@ -199,7 +200,7 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
public UserModel getUserByUsername(RealmModel realm, String username) {
|
||||||
if (!userPasswords.containsKey(translateUserName(username))) {
|
if (!userPasswords.containsKey(translateUserName(username))) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -208,7 +209,7 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
public UserModel getUserByEmail(RealmModel realm, String email) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,17 +297,14 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
|
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
Stream<String> userStream = userPasswords.keySet().stream().sorted();
|
Stream<String> userStream = userPasswords.keySet().stream().sorted();
|
||||||
if (firstResult > 0)
|
|
||||||
userStream = userStream.skip(firstResult);
|
return paginatedStream(userStream, firstResult, maxResults).map(userName -> createUser(realm, userName));
|
||||||
if (maxResults >= 0)
|
|
||||||
userStream = userStream.limit(maxResults);
|
|
||||||
return userStream.map(userName -> createUser(realm, userName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search) {
|
||||||
String tSearch = translateUserName(search);
|
String tSearch = translateUserName(search);
|
||||||
return userPasswords.keySet().stream()
|
return userPasswords.keySet().stream()
|
||||||
.sorted()
|
.sorted()
|
||||||
|
@ -315,25 +313,17 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
||||||
String tSearch = translateUserName(search);
|
String tSearch = translateUserName(search);
|
||||||
Stream<String> userStream = userPasswords.keySet().stream()
|
Stream<String> userStream = userPasswords.keySet().stream()
|
||||||
.sorted()
|
.sorted()
|
||||||
.filter(userName -> translateUserName(userName).contains(search));
|
.filter(userName -> translateUserName(userName).contains(search));
|
||||||
if (firstResult != null && firstResult > 0)
|
|
||||||
userStream = userStream.skip(firstResult);
|
return paginatedStream(userStream, firstResult, maxResults).map(userName -> createUser(realm, userName));
|
||||||
if (maxResults != null && maxResults >= 0)
|
|
||||||
userStream = userStream.limit(maxResults);
|
|
||||||
return userStream.map(userName -> createUser(realm, userName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params, Integer firstResult, Integer maxResults) {
|
||||||
return searchForUserStream(params, realm, 0, Integer.MAX_VALUE - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm, Integer firstResult, Integer maxResults) {
|
|
||||||
Stream<String> userStream = userPasswords.keySet().stream()
|
Stream<String> userStream = userPasswords.keySet().stream()
|
||||||
.sorted();
|
.sorted();
|
||||||
|
|
||||||
|
@ -356,28 +346,19 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstResult != null && firstResult > 0)
|
return paginatedStream(userStream, firstResult, maxResults).map(userName -> createUser(realm, userName));
|
||||||
userStream = userStream.skip(firstResult);
|
|
||||||
if (maxResults != null && maxResults >= 0)
|
|
||||||
userStream = userStream.limit(maxResults);
|
|
||||||
return userStream.map(userName -> createUser(realm, userName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
|
||||||
return getMembershipStream(realm, group, firstResult, maxResults)
|
return getMembershipStream(realm, group, firstResult == null ? -1 : firstResult, maxResults == null ? -1 : maxResults)
|
||||||
.map(userName -> createUser(realm, userName));
|
.map(userName -> createUser(realm, userName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
|
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
|
||||||
return getGroupMembersStream(realm, group, 0, Integer.MAX_VALUE - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
|
|
||||||
if (isImportEnabled()) {
|
if (isImportEnabled()) {
|
||||||
return session.userLocalStorage().searchForUserByUserAttributeStream(attrName, attrValue, realm);
|
return session.userLocalStorage().searchForUserByUserAttributeStream(realm, attrName, attrValue);
|
||||||
} else {
|
} else {
|
||||||
return session.userFederatedStorage().getUsersByUserAttributeStream(realm, attrName, attrValue)
|
return session.userFederatedStorage().getUsersByUserAttributeStream(realm, attrName, attrValue)
|
||||||
.map(userName -> createUser(realm, userName));
|
.map(userName -> createUser(realm, userName));
|
||||||
|
@ -409,15 +390,12 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<String> getMembershipStream(RealmModel realm, GroupModel group, int firstResult, int max) {
|
public Stream<String> getMembershipStream(RealmModel realm, GroupModel group, int firstResult, int max) {
|
||||||
Stream<String> userStream = userGroups.entrySet().stream()
|
Stream<String> userStream = paginatedStream(userGroups.entrySet().stream(), firstResult, max)
|
||||||
.filter(me -> me.getValue().contains(group.getId()))
|
.filter(me -> me.getValue().contains(group.getId()))
|
||||||
.map(Map.Entry::getKey)
|
.map(Map.Entry::getKey)
|
||||||
.filter(realmUser -> realmUser.startsWith(realm.getId()))
|
.filter(realmUser -> realmUser.startsWith(realm.getId()))
|
||||||
.map(realmUser -> realmUser.substring(realmUser.indexOf("/") + 1));
|
.map(realmUser -> realmUser.substring(realmUser.indexOf("/") + 1));
|
||||||
if (firstResult > 0)
|
|
||||||
userStream = userStream.skip(firstResult);
|
|
||||||
if (max >= 0)
|
|
||||||
userStream = userStream.limit(max);
|
|
||||||
return userStream;
|
return userStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,12 +40,15 @@ import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.keycloak.utils.StreamsUtil.paginatedStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class UserPropertyFileStorage implements UserLookupProvider, UserStorageProvider, UserQueryProvider, CredentialInputValidator {
|
public class UserPropertyFileStorage implements UserLookupProvider.Streams, UserStorageProvider, UserQueryProvider.Streams, CredentialInputValidator {
|
||||||
|
|
||||||
protected Properties userPasswords;
|
protected Properties userPasswords;
|
||||||
protected ComponentModel model;
|
protected ComponentModel model;
|
||||||
|
@ -61,7 +64,7 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
public UserModel getUserById(RealmModel realm, String id) {
|
||||||
StorageId storageId = new StorageId(id);
|
StorageId storageId = new StorageId(id);
|
||||||
final String username = storageId.getExternalId();
|
final String username = storageId.getExternalId();
|
||||||
if (!userPasswords.containsKey(username)) return null;
|
if (!userPasswords.containsKey(username)) return null;
|
||||||
|
@ -92,14 +95,14 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
public UserModel getUserByUsername(RealmModel realm, String username) {
|
||||||
if (!userPasswords.containsKey(username)) return null;
|
if (!userPasswords.containsKey(username)) return null;
|
||||||
|
|
||||||
return createUser(realm, username);
|
return createUser(realm, username);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
public UserModel getUserByEmail(RealmModel realm, String email) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,67 +148,47 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> getUsers(RealmModel realm) {
|
public Stream<UserModel> getUsersStream(RealmModel realm) {
|
||||||
List<UserModel> users = new LinkedList<>();
|
return userPasswords.keySet().stream()
|
||||||
for (Object username : userPasswords.keySet()) {
|
.map(username -> createUser(realm, (String) username));
|
||||||
users.add(createUser(realm, (String)username));
|
|
||||||
}
|
|
||||||
return users;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> searchForUser(Map<String, String> attributes, RealmModel realm) {
|
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
return searchForUser(attributes, realm, 0, Integer.MAX_VALUE - 1);
|
if (maxResults != null && maxResults == 0) return Stream.empty();
|
||||||
|
return paginatedStream(userPasswords.keySet().stream(), firstResult, maxResults)
|
||||||
|
.map(username -> createUser(realm, (String) username));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
||||||
if (maxResults == 0) return Collections.EMPTY_LIST;
|
return searchForUser(realm, search, firstResult, maxResults, username -> username.contains(search));
|
||||||
List<UserModel> users = new LinkedList<>();
|
|
||||||
int count = 0;
|
|
||||||
for (Object un : userPasswords.keySet()) {
|
|
||||||
if (count++ < firstResult) continue;
|
|
||||||
String username = (String)un;
|
|
||||||
users.add(createUser(realm, username));
|
|
||||||
if (users.size() + 1 > maxResults) break;
|
|
||||||
}
|
|
||||||
return users;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes, Integer firstResult, Integer maxResults) {
|
||||||
return searchForUser(search, realm, firstResult, maxResults, username -> username.contains(search));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> searchForUser(Map<String, String> attributes, RealmModel realm, int firstResult, int maxResults) {
|
|
||||||
String search = Optional.ofNullable(attributes.get(UserModel.USERNAME))
|
String search = Optional.ofNullable(attributes.get(UserModel.USERNAME))
|
||||||
.orElseGet(()-> attributes.get(UserModel.SEARCH));
|
.orElseGet(()-> attributes.get(UserModel.SEARCH));
|
||||||
if (search == null) return Collections.EMPTY_LIST;
|
if (search == null) return Stream.empty();
|
||||||
Predicate<String> p = Boolean.valueOf(attributes.getOrDefault(UserModel.EXACT, Boolean.FALSE.toString()))
|
Predicate<String> p = Boolean.valueOf(attributes.getOrDefault(UserModel.EXACT, Boolean.FALSE.toString()))
|
||||||
? username -> username.equals(search)
|
? username -> username.equals(search)
|
||||||
: username -> username.contains(search);
|
: username -> username.contains(search);
|
||||||
return searchForUser(search, realm, firstResult, maxResults, p);
|
return searchForUser(realm, search, firstResult, maxResults, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) {
|
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
|
||||||
return Collections.EMPTY_LIST;
|
return Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> getGroupMembers(RealmModel realm, GroupModel group) {
|
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
|
||||||
return Collections.EMPTY_LIST;
|
return Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> searchForUser(String search, RealmModel realm) {
|
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
|
||||||
return searchForUser(search, realm, 0, Integer.MAX_VALUE - 1);
|
return Stream.empty();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
|
|
||||||
return Collections.EMPTY_LIST;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -213,20 +196,11 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults, Predicate<String> matcher) {
|
private Stream<UserModel> searchForUser(RealmModel realm, String search, Integer firstResult, Integer maxResults, Predicate<String> matcher) {
|
||||||
if (maxResults == 0) return Collections.EMPTY_LIST;
|
if (maxResults != null && maxResults == 0) return Stream.empty();
|
||||||
List<UserModel> users = new LinkedList<>();
|
return paginatedStream(userPasswords.keySet().stream(), firstResult, maxResults)
|
||||||
int count = 0;
|
.map(String.class::cast)
|
||||||
for (Object un : userPasswords.keySet()) {
|
.filter(matcher)
|
||||||
String username = (String)un;
|
.map(username -> createUser(realm, username));
|
||||||
if (matcher.test(username)) {
|
|
||||||
if (count++ < firstResult) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
users.add(createUser(realm, username));
|
|
||||||
if (users.size() + 1 > maxResults) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return users;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ public class SyncDummyUserFederationProviderFactory extends DummyUserFederationP
|
||||||
// KEYCLOAK-2412 : Just remove and add some users for testing purposes
|
// KEYCLOAK-2412 : Just remove and add some users for testing purposes
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
String username = "dummyuser-" + i;
|
String username = "dummyuser-" + i;
|
||||||
UserModel user = session.userLocalStorage().getUserByUsername(username, realm);
|
UserModel user = session.userLocalStorage().getUserByUsername(realm, username);
|
||||||
|
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
session.userLocalStorage().removeUser(realm, user);
|
session.userLocalStorage().removeUser(realm, user);
|
||||||
|
|
|
@ -592,7 +592,7 @@ public class TestingResourceProvider implements RealmResourceProvider {
|
||||||
RealmModel realm = session.realms().getRealm(realmName);
|
RealmModel realm = session.realms().getRealm(realmName);
|
||||||
if (realm == null) return false;
|
if (realm == null) return false;
|
||||||
UserProvider userProvider = session.getProvider(UserProvider.class);
|
UserProvider userProvider = session.getProvider(UserProvider.class);
|
||||||
UserModel user = userProvider.getUserByUsername(userName, realm);
|
UserModel user = userProvider.getUserByUsername(realm, userName);
|
||||||
return session.userCredentialManager().isValid(realm, user, UserCredentialModel.password(password));
|
return session.userCredentialManager().isValid(realm, user, UserCredentialModel.password(password));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,7 +604,7 @@ public class TestingResourceProvider implements RealmResourceProvider {
|
||||||
@QueryParam("userId") String userId,
|
@QueryParam("userId") String userId,
|
||||||
@QueryParam("userName") String userName) {
|
@QueryParam("userName") String userName) {
|
||||||
RealmModel realm = getRealmByName(realmName);
|
RealmModel realm = getRealmByName(realmName);
|
||||||
UserModel foundFederatedUser = session.users().getUserByFederatedIdentity(new FederatedIdentityModel(identityProvider, userId, userName), realm);
|
UserModel foundFederatedUser = session.users().getUserByFederatedIdentity(realm, new FederatedIdentityModel(identityProvider, userId, userName));
|
||||||
if (foundFederatedUser == null) return null;
|
if (foundFederatedUser == null) return null;
|
||||||
return ModelToRepresentation.toRepresentation(session, realm, foundFederatedUser);
|
return ModelToRepresentation.toRepresentation(session, realm, foundFederatedUser);
|
||||||
}
|
}
|
||||||
|
@ -616,7 +616,7 @@ public class TestingResourceProvider implements RealmResourceProvider {
|
||||||
@QueryParam("userName") String userName) {
|
@QueryParam("userName") String userName) {
|
||||||
RealmModel realm = getRealmByName(realmName);
|
RealmModel realm = getRealmByName(realmName);
|
||||||
DummyUserFederationProviderFactory factory = (DummyUserFederationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, "dummy");
|
DummyUserFederationProviderFactory factory = (DummyUserFederationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, "dummy");
|
||||||
UserModel user = factory.create(session, null).getUserByUsername(userName, realm);
|
UserModel user = factory.create(session, null).getUserByUsername(realm, userName);
|
||||||
if (user == null) return null;
|
if (user == null) return null;
|
||||||
return ModelToRepresentation.toRepresentation(session, realm, user);
|
return ModelToRepresentation.toRepresentation(session, realm, user);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class RunHelpers {
|
||||||
public FetchOnServer getRunOnServer() {
|
public FetchOnServer getRunOnServer() {
|
||||||
return (FetchOnServer) session -> {
|
return (FetchOnServer) session -> {
|
||||||
RealmModel realm = session.getContext().getRealm();
|
RealmModel realm = session.getContext().getRealm();
|
||||||
UserModel user = session.users().getUserByUsername(username, realm);
|
UserModel user = session.users().getUserByUsername(realm, username);
|
||||||
List<CredentialModel> storedCredentialsByType = session.userCredentialManager()
|
List<CredentialModel> storedCredentialsByType = session.userCredentialManager()
|
||||||
.getStoredCredentialsByTypeStream(realm, user, CredentialRepresentation.PASSWORD)
|
.getStoredCredentialsByTypeStream(realm, user, CredentialRepresentation.PASSWORD)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
|
@ -481,7 +481,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
||||||
final String uId = userId; // Needed for run-on-server
|
final String uId = userId; // Needed for run-on-server
|
||||||
testingClient.server("test").run(session -> {
|
testingClient.server("test").run(session -> {
|
||||||
RealmModel realm = session.getContext().getRealm();
|
RealmModel realm = session.getContext().getRealm();
|
||||||
UserModel user = session.users().getUserById(uId, realm);
|
UserModel user = session.users().getUserById(realm, uId);
|
||||||
assertThat(user, Matchers.notNullValue());
|
assertThat(user, Matchers.notNullValue());
|
||||||
List<CredentialModel> storedCredentials = session.userCredentialManager()
|
List<CredentialModel> storedCredentials = session.userCredentialManager()
|
||||||
.getStoredCredentialsStream(realm, user).collect(Collectors.toList());
|
.getStoredCredentialsStream(realm, user).collect(Collectors.toList());
|
||||||
|
|
|
@ -65,7 +65,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import static org.hamcrest.Matchers.hasItem;
|
import static org.hamcrest.Matchers.hasItem;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
@ -331,7 +330,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
||||||
|
|
||||||
// test authorized
|
// test authorized
|
||||||
{
|
{
|
||||||
UserModel user = session.users().getUserByUsername("authorized", realm);
|
UserModel user = session.users().getUserByUsername(realm, "authorized");
|
||||||
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
|
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
|
||||||
Assert.assertTrue(permissionsForAdmin.users().canManage());
|
Assert.assertTrue(permissionsForAdmin.users().canManage());
|
||||||
Assert.assertTrue(permissionsForAdmin.roles().canMapRole(realmRole));
|
Assert.assertTrue(permissionsForAdmin.roles().canMapRole(realmRole));
|
||||||
|
@ -340,7 +339,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
||||||
}
|
}
|
||||||
// test composite role
|
// test composite role
|
||||||
{
|
{
|
||||||
UserModel user = session.users().getUserByUsername("authorizedComposite", realm);
|
UserModel user = session.users().getUserByUsername(realm, "authorizedComposite");
|
||||||
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
|
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
|
||||||
Assert.assertTrue(permissionsForAdmin.users().canManage());
|
Assert.assertTrue(permissionsForAdmin.users().canManage());
|
||||||
Assert.assertTrue(permissionsForAdmin.roles().canMapRole(realmRole));
|
Assert.assertTrue(permissionsForAdmin.roles().canMapRole(realmRole));
|
||||||
|
@ -350,7 +349,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
||||||
|
|
||||||
// test unauthorized
|
// test unauthorized
|
||||||
{
|
{
|
||||||
UserModel user = session.users().getUserByUsername("unauthorized", realm);
|
UserModel user = session.users().getUserByUsername(realm, "unauthorized");
|
||||||
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
|
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
|
||||||
Assert.assertFalse(permissionsForAdmin.users().canManage());
|
Assert.assertFalse(permissionsForAdmin.users().canManage());
|
||||||
Assert.assertFalse(permissionsForAdmin.roles().canMapRole(realmRole));
|
Assert.assertFalse(permissionsForAdmin.roles().canMapRole(realmRole));
|
||||||
|
@ -359,7 +358,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
||||||
}
|
}
|
||||||
// test unauthorized mapper
|
// test unauthorized mapper
|
||||||
{
|
{
|
||||||
UserModel user = session.users().getUserByUsername("unauthorizedMapper", realm);
|
UserModel user = session.users().getUserByUsername(realm, "unauthorizedMapper");
|
||||||
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
|
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
|
||||||
Assert.assertTrue(permissionsForAdmin.users().canManage());
|
Assert.assertTrue(permissionsForAdmin.users().canManage());
|
||||||
Assert.assertFalse(permissionsForAdmin.roles().canMapRole(realmRole));
|
Assert.assertFalse(permissionsForAdmin.roles().canMapRole(realmRole));
|
||||||
|
@ -369,12 +368,12 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
||||||
}
|
}
|
||||||
// test group management
|
// test group management
|
||||||
{
|
{
|
||||||
UserModel admin = session.users().getUserByUsername("groupManager", realm);
|
UserModel admin = session.users().getUserByUsername(realm, "groupManager");
|
||||||
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, admin);
|
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, admin);
|
||||||
UserModel user = session.users().getUserByUsername("authorized", realm);
|
UserModel user = session.users().getUserByUsername(realm, "authorized");
|
||||||
Assert.assertFalse(permissionsForAdmin.users().canManage(user));
|
Assert.assertFalse(permissionsForAdmin.users().canManage(user));
|
||||||
Assert.assertFalse(permissionsForAdmin.users().canView(user));
|
Assert.assertFalse(permissionsForAdmin.users().canView(user));
|
||||||
UserModel member = session.users().getUserByUsername("groupMember", realm);
|
UserModel member = session.users().getUserByUsername(realm, "groupMember");
|
||||||
Assert.assertTrue(permissionsForAdmin.users().canManage(member));
|
Assert.assertTrue(permissionsForAdmin.users().canManage(member));
|
||||||
Assert.assertTrue(permissionsForAdmin.users().canManageGroupMembership(member));
|
Assert.assertTrue(permissionsForAdmin.users().canManageGroupMembership(member));
|
||||||
Assert.assertTrue(permissionsForAdmin.users().canView(member));
|
Assert.assertTrue(permissionsForAdmin.users().canView(member));
|
||||||
|
@ -385,9 +384,9 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
||||||
}
|
}
|
||||||
// test client.mapRoles
|
// test client.mapRoles
|
||||||
{
|
{
|
||||||
UserModel admin = session.users().getUserByUsername("clientMapper", realm);
|
UserModel admin = session.users().getUserByUsername(realm, "clientMapper");
|
||||||
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, admin);
|
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, admin);
|
||||||
UserModel user = session.users().getUserByUsername("authorized", realm);
|
UserModel user = session.users().getUserByUsername(realm, "authorized");
|
||||||
Assert.assertTrue(permissionsForAdmin.users().canManage(user));
|
Assert.assertTrue(permissionsForAdmin.users().canManage(user));
|
||||||
Assert.assertFalse(permissionsForAdmin.roles().canMapRole(realmRole));
|
Assert.assertFalse(permissionsForAdmin.roles().canMapRole(realmRole));
|
||||||
Assert.assertTrue(permissionsForAdmin.roles().canMapRole(clientRole));
|
Assert.assertTrue(permissionsForAdmin.roles().canMapRole(clientRole));
|
||||||
|
|
|
@ -281,7 +281,7 @@ public class ImpersonationTest extends AbstractKeycloakTest {
|
||||||
final String userId = impersonatedUserId;
|
final String userId = impersonatedUserId;
|
||||||
final UserSessionNotesHolder notesHolder = testingClient.server("test").fetch(session -> {
|
final UserSessionNotesHolder notesHolder = testingClient.server("test").fetch(session -> {
|
||||||
final RealmModel realm = session.realms().getRealmByName("test");
|
final RealmModel realm = session.realms().getRealmByName("test");
|
||||||
final UserModel user = session.users().getUserById(userId, realm);
|
final UserModel user = session.users().getUserById(realm, userId);
|
||||||
final UserSessionModel userSession = session.sessions().getUserSessionsStream(realm, user).findFirst().get();
|
final UserSessionModel userSession = session.sessions().getUserSessionsStream(realm, user).findFirst().get();
|
||||||
return new UserSessionNotesHolder(userSession.getNotes());
|
return new UserSessionNotesHolder(userSession.getNotes());
|
||||||
}, UserSessionNotesHolder.class);
|
}, UserSessionNotesHolder.class);
|
||||||
|
|
|
@ -563,7 +563,7 @@ public class PolicyEvaluationTest extends AbstractAuthzTest {
|
||||||
|
|
||||||
public static void testCheckUserAttributes(KeycloakSession session) {
|
public static void testCheckUserAttributes(KeycloakSession session) {
|
||||||
RealmModel realm = session.realms().getRealmByName("authz-test");
|
RealmModel realm = session.realms().getRealmByName("authz-test");
|
||||||
UserModel jdoe = session.users().getUserByUsername("jdoe", realm);
|
UserModel jdoe = session.users().getUserByUsername(realm, "jdoe");
|
||||||
|
|
||||||
jdoe.setAttribute("a1", Arrays.asList("1", "2"));
|
jdoe.setAttribute("a1", Arrays.asList("1", "2"));
|
||||||
jdoe.setSingleAttribute("a2", "3");
|
jdoe.setSingleAttribute("a2", "3");
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.keycloak.testsuite.authz;
|
package org.keycloak.testsuite.authz;
|
||||||
|
|
||||||
import org.jboss.resteasy.spi.ResteasyUriInfo;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.admin.client.resource.RealmResource;
|
import org.keycloak.admin.client.resource.RealmResource;
|
||||||
|
@ -16,8 +15,6 @@ import org.keycloak.representations.idm.authorization.*;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@AuthServerContainerExclude(AuthServer.REMOTE)
|
@AuthServerContainerExclude(AuthServer.REMOTE)
|
||||||
|
@ -141,7 +138,7 @@ public class UmaRepresentationTest extends AbstractResourceServerTest {
|
||||||
|
|
||||||
AuthorizationBean authorizationBean = new AuthorizationBean(session, null, session.getContext().getUri());
|
AuthorizationBean authorizationBean = new AuthorizationBean(session, null, session.getContext().getUri());
|
||||||
ClientModel client = session.getContext().getRealm().getClientByClientId("resource-server-test");
|
ClientModel client = session.getContext().getRealm().getClientByClientId("resource-server-test");
|
||||||
UserModel user = session.userStorageManager().getUserByUsername("marta", session.getContext().getRealm());
|
UserModel user = session.userStorageManager().getUserByUsername(session.getContext().getRealm(), "marta");
|
||||||
ResourceBean resourceBean = authorizationBean.new ResourceBean(
|
ResourceBean resourceBean = authorizationBean.new ResourceBean(
|
||||||
authorization.getStoreFactory().getResourceStore().findByName(
|
authorization.getStoreFactory().getResourceStore().findByName(
|
||||||
"Resource A", user.getId(), client.getId()
|
"Resource A", user.getId(), client.getId()
|
||||||
|
|
|
@ -169,9 +169,9 @@ public class AccountLinkTest extends AbstractKeycloakTest {
|
||||||
|
|
||||||
private static void checkEmptyFederatedIdentities(KeycloakSession session) {
|
private static void checkEmptyFederatedIdentities(KeycloakSession session) {
|
||||||
RealmModel realm = session.getContext().getRealm();
|
RealmModel realm = session.getContext().getRealm();
|
||||||
UserModel user = session.users().getUserByUsername("child", realm);
|
UserModel user = session.users().getUserByUsername(realm, "child");
|
||||||
assertEquals(0, session.users().getFederatedIdentitiesStream(user, realm).count());
|
assertEquals(0, session.users().getFederatedIdentitiesStream(realm, user).count());
|
||||||
assertNull(session.users().getFederatedIdentity(user, PARENT_IDP, realm));
|
assertNull(session.users().getFederatedIdentity(realm, user, PARENT_IDP));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void testAccountLink(String childUsername, String childPassword, String childIdp) {
|
protected void testAccountLink(String childUsername, String childPassword, String childIdp) {
|
||||||
|
|
|
@ -83,7 +83,7 @@ final class BrokerRunOnServerUtil {
|
||||||
RealmModel realm = session.getContext().getRealm();
|
RealmModel realm = session.getContext().getRealm();
|
||||||
ClientModel brokerClient = realm.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID);
|
ClientModel brokerClient = realm.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID);
|
||||||
RoleModel readTokenRole = brokerClient.getRole(Constants.READ_TOKEN_ROLE);
|
RoleModel readTokenRole = brokerClient.getRole(Constants.READ_TOKEN_ROLE);
|
||||||
UserModel user = session.users().getUserByUsername(username, realm);
|
UserModel user = session.users().getUserByUsername(realm, username);
|
||||||
user.grantRole(readTokenRole);
|
user.grantRole(readTokenRole);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ final class BrokerRunOnServerUtil {
|
||||||
RealmModel realm = session.getContext().getRealm();
|
RealmModel realm = session.getContext().getRealm();
|
||||||
ClientModel brokerClient = realm.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID);
|
ClientModel brokerClient = realm.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID);
|
||||||
RoleModel readTokenRole = brokerClient.getRole(Constants.READ_TOKEN_ROLE);
|
RoleModel readTokenRole = brokerClient.getRole(Constants.READ_TOKEN_ROLE);
|
||||||
UserModel user = session.users().getUserByUsername(username, realm);
|
UserModel user = session.users().getUserByUsername(realm, username);
|
||||||
user.deleteRoleMapping(readTokenRole);
|
user.deleteRoleMapping(readTokenRole);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ final class BrokerRunOnServerUtil {
|
||||||
static RunOnServer assertHardCodedSessionNote() {
|
static RunOnServer assertHardCodedSessionNote() {
|
||||||
return (session) -> {
|
return (session) -> {
|
||||||
RealmModel realm = session.realms().getRealmByName("consumer");
|
RealmModel realm = session.realms().getRealmByName("consumer");
|
||||||
UserModel user = session.users().getUserByUsername("testuser", realm);
|
UserModel user = session.users().getUserByUsername(realm, "testuser");
|
||||||
UserSessionModel sessions = session.sessions().getUserSessionsStream(realm, user).findFirst().get();
|
UserSessionModel sessions = session.sessions().getUserSessionsStream(realm, user).findFirst().get();
|
||||||
assertEquals("sessionvalue", sessions.getNote("user-session-attr"));
|
assertEquals("sessionvalue", sessions.getNote("user-session-attr"));
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,7 +28,6 @@ import org.keycloak.authentication.requiredactions.TermsAndConditions;
|
||||||
import org.keycloak.authorization.model.Policy;
|
import org.keycloak.authorization.model.Policy;
|
||||||
import org.keycloak.authorization.model.ResourceServer;
|
import org.keycloak.authorization.model.ResourceServer;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
import org.keycloak.credential.CredentialModel;
|
|
||||||
import org.keycloak.models.AuthenticationExecutionModel;
|
import org.keycloak.models.AuthenticationExecutionModel;
|
||||||
import org.keycloak.models.AuthenticationFlowBindings;
|
import org.keycloak.models.AuthenticationFlowBindings;
|
||||||
import org.keycloak.models.AuthenticationFlowModel;
|
import org.keycloak.models.AuthenticationFlowModel;
|
||||||
|
@ -294,7 +293,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
|
||||||
public void testBrowserContinueRequiredAction() throws Exception {
|
public void testBrowserContinueRequiredAction() throws Exception {
|
||||||
testingClient.server().run(session -> {
|
testingClient.server().run(session -> {
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = session.realms().getRealmByName("test");
|
||||||
UserModel user = session.users().getUserByUsername("wburke", realm);
|
UserModel user = session.users().getUserByUsername(realm, "wburke");
|
||||||
user.addRequiredAction("dummy");
|
user.addRequiredAction("dummy");
|
||||||
});
|
});
|
||||||
testInstall();
|
testInstall();
|
||||||
|
@ -439,7 +438,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
|
||||||
public void testTerms() throws Exception {
|
public void testTerms() throws Exception {
|
||||||
testingClient.server().run(session -> {
|
testingClient.server().run(session -> {
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = session.realms().getRealmByName("test");
|
||||||
UserModel user = session.users().getUserByUsername("wburke", realm);
|
UserModel user = session.users().getUserByUsername(realm, "wburke");
|
||||||
user.addRequiredAction(TermsAndConditions.PROVIDER_ID);
|
user.addRequiredAction(TermsAndConditions.PROVIDER_ID);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -466,7 +465,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
|
||||||
// expects that updateProfile is a passthrough
|
// expects that updateProfile is a passthrough
|
||||||
testingClient.server().run(session -> {
|
testingClient.server().run(session -> {
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = session.realms().getRealmByName("test");
|
||||||
UserModel user = session.users().getUserByUsername("wburke", realm);
|
UserModel user = session.users().getUserByUsername(realm, "wburke");
|
||||||
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE);
|
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -496,7 +495,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
|
||||||
|
|
||||||
testingClient.server().run(session -> {
|
testingClient.server().run(session -> {
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = session.realms().getRealmByName("test");
|
||||||
UserModel user = session.users().getUserByUsername("wburke", realm);
|
UserModel user = session.users().getUserByUsername(realm, "wburke");
|
||||||
user.removeRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE);
|
user.removeRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -507,7 +506,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
|
||||||
public void testUpdatePassword() throws Exception {
|
public void testUpdatePassword() throws Exception {
|
||||||
testingClient.server().run(session -> {
|
testingClient.server().run(session -> {
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = session.realms().getRealmByName("test");
|
||||||
UserModel user = session.users().getUserByUsername("wburke", realm);
|
UserModel user = session.users().getUserByUsername(realm, "wburke");
|
||||||
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
|
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -548,7 +547,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
|
||||||
|
|
||||||
testingClient.server().run(session -> {
|
testingClient.server().run(session -> {
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = session.realms().getRealmByName("test");
|
||||||
UserModel user = session.users().getUserByUsername("wburke", realm);
|
UserModel user = session.users().getUserByUsername(realm, "wburke");
|
||||||
session.userCredentialManager().updateCredential(realm, user, UserCredentialModel.password("password"));
|
session.userCredentialManager().updateCredential(realm, user, UserCredentialModel.password("password"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -562,7 +561,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
|
||||||
public void testConfigureTOTP() throws Exception {
|
public void testConfigureTOTP() throws Exception {
|
||||||
testingClient.server().run(session -> {
|
testingClient.server().run(session -> {
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = session.realms().getRealmByName("test");
|
||||||
UserModel user = session.users().getUserByUsername("wburke", realm);
|
UserModel user = session.users().getUserByUsername(realm, "wburke");
|
||||||
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
|
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -631,7 +630,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
|
||||||
} finally {
|
} finally {
|
||||||
testingClient.server().run(session -> {
|
testingClient.server().run(session -> {
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = session.realms().getRealmByName("test");
|
||||||
UserModel user = session.users().getUserByUsername("wburke", realm);
|
UserModel user = session.users().getUserByUsername(realm, "wburke");
|
||||||
session.userCredentialManager().getStoredCredentialsByTypeStream(realm, user, OTPCredentialModel.TYPE)
|
session.userCredentialManager().getStoredCredentialsByTypeStream(realm, user, OTPCredentialModel.TYPE)
|
||||||
.collect(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
.forEach(model -> session.userCredentialManager().removeStoredCredential(realm, user, model.getId()));
|
.forEach(model -> session.userCredentialManager().removeStoredCredential(realm, user, model.getId()));
|
||||||
|
@ -648,7 +647,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
|
||||||
public void testVerifyEmail() throws Exception {
|
public void testVerifyEmail() throws Exception {
|
||||||
testingClient.server().run(session -> {
|
testingClient.server().run(session -> {
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = session.realms().getRealmByName("test");
|
||||||
UserModel user = session.users().getUserByUsername("test-user@localhost", realm);
|
UserModel user = session.users().getUserByUsername(realm, "test-user@localhost");
|
||||||
user.addRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
|
user.addRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@ public class LDAPBinaryAttributesTest extends AbstractLDAPTest {
|
||||||
String joeId = joe.getId();
|
String joeId = joe.getId();
|
||||||
testingClient.server().run(session -> {
|
testingClient.server().run(session -> {
|
||||||
RealmModel test = session.realms().getRealmByName("test");
|
RealmModel test = session.realms().getRealmByName("test");
|
||||||
UserModel userById = session.userLocalStorage().getUserById(joeId, test);
|
UserModel userById = session.userLocalStorage().getUserById(test, joeId);
|
||||||
|
|
||||||
assertThat(userById.getAttributes().get(LDAPConstants.JPEG_PHOTO), is(nullValue()));
|
assertThat(userById.getAttributes().get(LDAPConstants.JPEG_PHOTO), is(nullValue()));
|
||||||
});
|
});
|
||||||
|
|
|
@ -48,7 +48,6 @@ import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
|
|
||||||
import javax.ws.rs.BadRequestException;
|
import javax.ws.rs.BadRequestException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -338,7 +337,7 @@ public class LDAPGroupMapperSyncTest extends AbstractLDAPTest {
|
||||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group12"));
|
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group12"));
|
||||||
|
|
||||||
// Load user from LDAP to Keycloak DB
|
// Load user from LDAP to Keycloak DB
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", realm);
|
UserModel john = session.users().getUserByUsername(realm, "johnkeycloak");
|
||||||
Set<GroupModel> johnGroups = john.getGroupsStream().collect(Collectors.toSet());
|
Set<GroupModel> johnGroups = john.getGroupsStream().collect(Collectors.toSet());
|
||||||
|
|
||||||
// Assert just those groups, which john was memberOf exists because they were lazily created
|
// Assert just those groups, which john was memberOf exists because they were lazily created
|
||||||
|
|
|
@ -87,8 +87,8 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
|
||||||
appRealm.updateComponent(mapperModel);
|
appRealm.updateComponent(mapperModel);
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername(appRealm, "johnkeycloak");
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
|
||||||
|
|
||||||
// 1 - Grant some groups in LDAP
|
// 1 - Grant some groups in LDAP
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
LDAPTestContext ctx = LDAPTestContext.init(session);
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = ctx.getRealm();
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel johnDb = session.userLocalStorage().getUserByUsername("johnkeycloak", appRealm);
|
UserModel johnDb = session.userLocalStorage().getUserByUsername(appRealm, "johnkeycloak");
|
||||||
Assert.assertEquals(2, johnDb.getGroupsStream().count());
|
Assert.assertEquals(2, johnDb.getGroupsStream().count());
|
||||||
Assert.assertEquals(2, johnDb.getGroupsStream("Gr", 0, 10).count());
|
Assert.assertEquals(2, johnDb.getGroupsStream("Gr", 0, 10).count());
|
||||||
Assert.assertEquals(1, johnDb.getGroupsStream("Gr", 1, 10).count());
|
Assert.assertEquals(1, johnDb.getGroupsStream("Gr", 1, 10).count());
|
||||||
|
@ -150,8 +150,8 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||||
GroupModel groupTeam20162017 = KeycloakModelUtils.findGroupByPath(appRealm, "Team 2016/2017");
|
GroupModel groupTeam20162017 = KeycloakModelUtils.findGroupByPath(appRealm, "Team 2016/2017");
|
||||||
GroupModel groupTeamChild20182019 = KeycloakModelUtils.findGroupByPath(appRealm, "defaultGroup1/Team Child 2018/2019");
|
GroupModel groupTeamChild20182019 = KeycloakModelUtils.findGroupByPath(appRealm, "defaultGroup1/Team Child 2018/2019");
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername(appRealm, "johnkeycloak");
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
|
||||||
|
|
||||||
Set<GroupModel> johnGroups = john.getGroupsStream().collect(Collectors.toSet());
|
Set<GroupModel> johnGroups = john.getGroupsStream().collect(Collectors.toSet());
|
||||||
Assert.assertEquals(4, johnGroups.size());
|
Assert.assertEquals(4, johnGroups.size());
|
||||||
|
@ -239,7 +239,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
LDAPTestContext ctx = LDAPTestContext.init(session);
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = ctx.getRealm();
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
|
||||||
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
||||||
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
||||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||||
|
@ -267,7 +267,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
LDAPTestContext ctx = LDAPTestContext.init(session);
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = ctx.getRealm();
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
|
||||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||||
|
|
||||||
// Add some group mapping to model. This should fail with no-import mode for LDAP provider READ_ONLY mode for the group mapper
|
// Add some group mapping to model. This should fail with no-import mode for LDAP provider READ_ONLY mode for the group mapper
|
||||||
|
@ -284,7 +284,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
LDAPTestContext ctx = LDAPTestContext.init(session);
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = ctx.getRealm();
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
|
||||||
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
||||||
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
||||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||||
|
@ -316,7 +316,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
||||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||||
|
|
||||||
UserModel maryDB = session.userLocalStorage().getUserByUsername("marykeycloak", appRealm);
|
UserModel maryDB = session.userLocalStorage().getUserByUsername(appRealm, "marykeycloak");
|
||||||
|
|
||||||
Set<GroupModel> maryDBGroups = maryDB.getGroupsStream().collect(Collectors.toSet());
|
Set<GroupModel> maryDBGroups = maryDB.getGroupsStream().collect(Collectors.toSet());
|
||||||
Assert.assertFalse(maryDBGroups.contains(group1));
|
Assert.assertFalse(maryDBGroups.contains(group1));
|
||||||
|
@ -337,7 +337,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
Assert.assertEquals(1, group12Members.size());
|
Assert.assertEquals(1, group12Members.size());
|
||||||
Assert.assertEquals("marykeycloak", group12Members.get(0).getUsername());
|
Assert.assertEquals("marykeycloak", group12Members.get(0).getUsername());
|
||||||
|
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
|
||||||
mary.leaveGroup(group12);
|
mary.leaveGroup(group12);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -362,8 +362,8 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
||||||
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
||||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername(appRealm, "johnkeycloak");
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
|
||||||
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
|
||||||
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ctx.getLdapProvider(), appRealm);
|
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ctx.getLdapProvider(), appRealm);
|
||||||
|
@ -417,7 +417,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
groupMapper.addGroupMappingInLDAP(appRealm, group12, robLdap);
|
groupMapper.addGroupMappingInLDAP(appRealm, group12, robLdap);
|
||||||
|
|
||||||
// Get user and check that he has requested groups from LDAP
|
// Get user and check that he has requested groups from LDAP
|
||||||
UserModel rob = session.users().getUserByUsername("robkeycloak", appRealm);
|
UserModel rob = session.users().getUserByUsername(appRealm, "robkeycloak");
|
||||||
Set<GroupModel> robGroups = rob.getGroupsStream().collect(Collectors.toSet());
|
Set<GroupModel> robGroups = rob.getGroupsStream().collect(Collectors.toSet());
|
||||||
|
|
||||||
Assert.assertFalse(robGroups.contains(group1));
|
Assert.assertFalse(robGroups.contains(group1));
|
||||||
|
@ -563,7 +563,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
RealmModel appRealm = ctx.getRealm();
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
// Get user in Keycloak. Ensure that he is member of requested group
|
// Get user in Keycloak. Ensure that he is member of requested group
|
||||||
UserModel carlos = session.users().getUserByUsername("carloskeycloak", appRealm);
|
UserModel carlos = session.users().getUserByUsername(appRealm, "carloskeycloak");
|
||||||
Set<GroupModel> carlosGroups = carlos.getGroupsStream().collect(Collectors.toSet());
|
Set<GroupModel> carlosGroups = carlos.getGroupsStream().collect(Collectors.toSet());
|
||||||
|
|
||||||
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
||||||
|
@ -608,7 +608,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
LDAPTestContext ctx = LDAPTestContext.init(session);
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = ctx.getRealm();
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername(appRealm, "johnkeycloak");
|
||||||
|
|
||||||
GroupModel group4 = KeycloakModelUtils.findGroupByPath(appRealm, "/group4");
|
GroupModel group4 = KeycloakModelUtils.findGroupByPath(appRealm, "/group4");
|
||||||
john.joinGroup(group4);
|
john.joinGroup(group4);
|
||||||
|
@ -628,7 +628,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
LDAPTestContext ctx = LDAPTestContext.init(session);
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = ctx.getRealm();
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername(appRealm, "johnkeycloak");
|
||||||
|
|
||||||
GroupModel group14 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group14");
|
GroupModel group14 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group14");
|
||||||
GroupModel group3 = KeycloakModelUtils.findGroupByPath(appRealm, "/group3");
|
GroupModel group3 = KeycloakModelUtils.findGroupByPath(appRealm, "/group3");
|
||||||
|
@ -747,7 +747,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
GroupModel kcBigGroup = KeycloakModelUtils.findGroupByPath(appRealm, "/biggroup");
|
GroupModel kcBigGroup = KeycloakModelUtils.findGroupByPath(appRealm, "/biggroup");
|
||||||
// check all the users have the group assigned
|
// check all the users have the group assigned
|
||||||
for (int i = 0; i < membersToTest; i++) {
|
for (int i = 0; i < membersToTest; i++) {
|
||||||
UserModel kcUser = session.users().getUserByUsername(String.format("user%02d", i), appRealm);
|
UserModel kcUser = session.users().getUserByUsername(appRealm, String.format("user%02d", i));
|
||||||
Assert.assertTrue("User contains biggroup " + i, kcUser.getGroupsStream().collect(Collectors.toSet()).contains(kcBigGroup));
|
Assert.assertTrue("User contains biggroup " + i, kcUser.getGroupsStream().collect(Collectors.toSet()).contains(kcBigGroup));
|
||||||
}
|
}
|
||||||
// check the group contains all the users as member
|
// check the group contains all the users as member
|
||||||
|
@ -794,7 +794,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
// check everything is OK
|
// check everything is OK
|
||||||
GroupModel kcDeleteGroup = KeycloakModelUtils.findGroupByPath(appRealm, "/deletegroup");
|
GroupModel kcDeleteGroup = KeycloakModelUtils.findGroupByPath(appRealm, "/deletegroup");
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
|
||||||
List<UserModel> groupMembers = session.users().getGroupMembersStream(appRealm, kcDeleteGroup, 0, 5)
|
List<UserModel> groupMembers = session.users().getGroupMembersStream(appRealm, kcDeleteGroup, 0, 5)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
Assert.assertEquals(1, groupMembers.size());
|
Assert.assertEquals(1, groupMembers.size());
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class LDAPHardcodedAttributeTest extends AbstractLDAPTest {
|
||||||
LDAPTestContext ctx = LDAPTestContext.init(session);
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = ctx.getRealm();
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel user = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel user = session.users().getUserByUsername(appRealm, "johnkeycloak");
|
||||||
Assert.assertNotNull(user);
|
Assert.assertNotNull(user);
|
||||||
Assert.assertTrue(user.isEmailVerified());
|
Assert.assertTrue(user.isEmailVerified());
|
||||||
Assert.assertEquals("en", user.getFirstAttribute("locale"));
|
Assert.assertEquals("en", user.getFirstAttribute("locale"));
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue