user fed spi querying tests
This commit is contained in:
parent
0315bd0b87
commit
72d134748c
16 changed files with 879 additions and 67 deletions
|
@ -17,7 +17,14 @@
|
|||
|
||||
package org.keycloak.common.util.reflections;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utility class for Types
|
||||
|
@ -68,4 +75,564 @@ public class Types {
|
|||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the genericType of a certain class?
|
||||
*/
|
||||
public static boolean isA(Class clazz, ParameterizedType pType)
|
||||
{
|
||||
return clazz.isAssignableFrom((Class) pType.getRawType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index-th type argument.
|
||||
*/
|
||||
public static Class getArgumentType(ParameterizedType pType, int index)
|
||||
{
|
||||
return (Class) pType.getActualTypeArguments()[index];
|
||||
}
|
||||
|
||||
public static Class getTemplateParameterOfInterface(Class base, Class desiredInterface)
|
||||
{
|
||||
Object rtn = searchForInterfaceTemplateParameter(base, desiredInterface);
|
||||
if (rtn != null && rtn instanceof Class) return (Class) rtn;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static Object searchForInterfaceTemplateParameter(Class base, Class desiredInterface)
|
||||
{
|
||||
for (int i = 0; i < base.getInterfaces().length; i++)
|
||||
{
|
||||
Class intf = base.getInterfaces()[i];
|
||||
if (intf.equals(desiredInterface))
|
||||
{
|
||||
Type generic = base.getGenericInterfaces()[i];
|
||||
if (generic instanceof ParameterizedType)
|
||||
{
|
||||
ParameterizedType p = (ParameterizedType) generic;
|
||||
Type type = p.getActualTypeArguments()[0];
|
||||
Class rtn = getRawTypeNoException(type);
|
||||
if (rtn != null) return rtn;
|
||||
return type;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (base.getSuperclass() == null || base.getSuperclass().equals(Object.class)) return null;
|
||||
Object rtn = searchForInterfaceTemplateParameter(base.getSuperclass(), desiredInterface);
|
||||
if (rtn == null || rtn instanceof Class) return rtn;
|
||||
if (!(rtn instanceof TypeVariable)) return null;
|
||||
|
||||
String name = ((TypeVariable) rtn).getName();
|
||||
int index = -1;
|
||||
TypeVariable[] variables = base.getSuperclass().getTypeParameters();
|
||||
if (variables == null || variables.length < 1) return null;
|
||||
|
||||
for (int i = 0; i < variables.length; i++)
|
||||
{
|
||||
if (variables[i].getName().equals(name)) index = i;
|
||||
}
|
||||
if (index == -1) return null;
|
||||
|
||||
|
||||
Type genericSuperclass = base.getGenericSuperclass();
|
||||
if (!(genericSuperclass instanceof ParameterizedType)) return null;
|
||||
|
||||
ParameterizedType pt = (ParameterizedType) genericSuperclass;
|
||||
Type type = pt.getActualTypeArguments()[index];
|
||||
|
||||
Class clazz = getRawTypeNoException(type);
|
||||
if (clazz != null) return clazz;
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See if the two methods are compatible, that is they have the same relative signature
|
||||
*
|
||||
* @param method
|
||||
* @param intfMethod
|
||||
* @return
|
||||
*/
|
||||
public static boolean isCompatible(Method method, Method intfMethod)
|
||||
{
|
||||
if (method == intfMethod) return true;
|
||||
|
||||
if (!method.getName().equals(intfMethod.getName())) return false;
|
||||
if (method.getParameterTypes().length != intfMethod.getParameterTypes().length) return false;
|
||||
|
||||
for (int i = 0; i < method.getParameterTypes().length; i++)
|
||||
{
|
||||
Class rootParam = method.getParameterTypes()[i];
|
||||
Class intfParam = intfMethod.getParameterTypes()[i];
|
||||
if (!intfParam.isAssignableFrom(rootParam)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a method and a root class, find the actual method declared in the root that implements the method.
|
||||
*
|
||||
* @param clazz
|
||||
* @param intfMethod
|
||||
* @return
|
||||
*/
|
||||
public static Method getImplementingMethod(Class clazz, Method intfMethod)
|
||||
{
|
||||
Class<?> declaringClass = intfMethod.getDeclaringClass();
|
||||
if (declaringClass.equals(clazz)) return intfMethod;
|
||||
|
||||
Class[] paramTypes = intfMethod.getParameterTypes();
|
||||
|
||||
if (declaringClass.getTypeParameters().length > 0 && paramTypes.length > 0)
|
||||
{
|
||||
Type[] intfTypes = findParameterizedTypes(clazz, declaringClass);
|
||||
Map<String, Type> typeVarMap = new HashMap<String, Type>();
|
||||
TypeVariable<? extends Class<?>>[] vars = declaringClass.getTypeParameters();
|
||||
for (int i = 0; i < vars.length; i++)
|
||||
{
|
||||
if (intfTypes != null && i < intfTypes.length)
|
||||
{
|
||||
typeVarMap.put(vars[i].getName(), intfTypes[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interface type parameters may not have been filled out
|
||||
typeVarMap.put(vars[i].getName(), vars[i].getGenericDeclaration());
|
||||
}
|
||||
}
|
||||
Type[] paramGenericTypes = intfMethod.getGenericParameterTypes();
|
||||
paramTypes = new Class[paramTypes.length];
|
||||
|
||||
for (int i = 0; i < paramTypes.length; i++)
|
||||
{
|
||||
if (paramGenericTypes[i] instanceof TypeVariable)
|
||||
{
|
||||
TypeVariable tv = (TypeVariable)paramGenericTypes[i];
|
||||
Type t = typeVarMap.get(tv.getName());
|
||||
if (t == null)
|
||||
{
|
||||
throw new RuntimeException("Unable to resolve type variable");
|
||||
}
|
||||
paramTypes[i] = getRawType(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
paramTypes[i] = getRawType(paramGenericTypes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return clazz.getMethod(intfMethod.getName(), paramTypes);
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Method tmp = clazz.getMethod(intfMethod.getName(), intfMethod.getParameterTypes());
|
||||
return tmp;
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
|
||||
}
|
||||
return intfMethod;
|
||||
}
|
||||
|
||||
|
||||
public static Class<?> getRawType(Type type)
|
||||
{
|
||||
if (type instanceof Class<?>)
|
||||
{
|
||||
// type is a normal class.
|
||||
return (Class<?>) type;
|
||||
|
||||
}
|
||||
else if (type instanceof ParameterizedType)
|
||||
{
|
||||
ParameterizedType parameterizedType = (ParameterizedType) type;
|
||||
Type rawType = parameterizedType.getRawType();
|
||||
return (Class<?>) rawType;
|
||||
}
|
||||
else if (type instanceof GenericArrayType)
|
||||
{
|
||||
final GenericArrayType genericArrayType = (GenericArrayType) type;
|
||||
final Class<?> componentRawType = getRawType(genericArrayType.getGenericComponentType());
|
||||
return Array.newInstance(componentRawType, 0).getClass();
|
||||
}
|
||||
else if (type instanceof TypeVariable)
|
||||
{
|
||||
final TypeVariable typeVar = (TypeVariable) type;
|
||||
if (typeVar.getBounds() != null && typeVar.getBounds().length > 0)
|
||||
{
|
||||
return getRawType(typeVar.getBounds()[0]);
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("unable to determine base class");
|
||||
}
|
||||
|
||||
|
||||
public static Class<?> getRawTypeNoException(Type type)
|
||||
{
|
||||
if (type instanceof Class<?>)
|
||||
{
|
||||
// type is a normal class.
|
||||
return (Class<?>) type;
|
||||
|
||||
}
|
||||
else if (type instanceof ParameterizedType)
|
||||
{
|
||||
ParameterizedType parameterizedType = (ParameterizedType) type;
|
||||
Type rawType = parameterizedType.getRawType();
|
||||
return (Class<?>) rawType;
|
||||
}
|
||||
else if (type instanceof GenericArrayType)
|
||||
{
|
||||
final GenericArrayType genericArrayType = (GenericArrayType) type;
|
||||
final Class<?> componentRawType = getRawType(genericArrayType.getGenericComponentType());
|
||||
return Array.newInstance(componentRawType, 0).getClass();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type argument from a parameterized type
|
||||
*
|
||||
* @param genericType
|
||||
* @return null if there is no type parameter
|
||||
*/
|
||||
public static Class<?> getTypeArgument(Type genericType)
|
||||
{
|
||||
if (!(genericType instanceof ParameterizedType)) return null;
|
||||
ParameterizedType parameterizedType = (ParameterizedType) genericType;
|
||||
Class<?> typeArg = (Class<?>) parameterizedType.getActualTypeArguments()[0];
|
||||
return typeArg;
|
||||
}
|
||||
|
||||
|
||||
public static Class getCollectionBaseType(Class type, Type genericType)
|
||||
{
|
||||
if (genericType instanceof ParameterizedType)
|
||||
{
|
||||
ParameterizedType parameterizedType = (ParameterizedType) genericType;
|
||||
Type componentGenericType = parameterizedType.getActualTypeArguments()[0];
|
||||
return getRawType(componentGenericType);
|
||||
}
|
||||
else if (genericType instanceof GenericArrayType)
|
||||
{
|
||||
final GenericArrayType genericArrayType = (GenericArrayType) genericType;
|
||||
Type componentGenericType = genericArrayType.getGenericComponentType();
|
||||
return getRawType(componentGenericType);
|
||||
}
|
||||
else if (type.isArray())
|
||||
{
|
||||
return type.getComponentType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static Class getMapKeyType(Type genericType)
|
||||
{
|
||||
if (genericType instanceof ParameterizedType)
|
||||
{
|
||||
ParameterizedType parameterizedType = (ParameterizedType) genericType;
|
||||
Type componentGenericType = parameterizedType.getActualTypeArguments()[0];
|
||||
return getRawType(componentGenericType);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Class getMapValueType(Type genericType)
|
||||
{
|
||||
if (genericType instanceof ParameterizedType)
|
||||
{
|
||||
ParameterizedType parameterizedType = (ParameterizedType) genericType;
|
||||
Type componentGenericType = parameterizedType.getActualTypeArguments()[1];
|
||||
return getRawType(componentGenericType);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Type resolveTypeVariables(Class<?> root, Type type)
|
||||
{
|
||||
if (type instanceof TypeVariable)
|
||||
{
|
||||
Type newType = resolveTypeVariable(root, (TypeVariable)type);
|
||||
return (newType == null) ? type : newType;
|
||||
}
|
||||
else if (type instanceof ParameterizedType)
|
||||
{
|
||||
final ParameterizedType param = (ParameterizedType)type;
|
||||
final Type[] actuals = new Type[param.getActualTypeArguments().length];
|
||||
for (int i = 0; i < actuals.length; i++)
|
||||
{
|
||||
Type newType = resolveTypeVariables(root, param.getActualTypeArguments()[i]);
|
||||
actuals[i] = newType == null ? param.getActualTypeArguments()[i] : newType;
|
||||
}
|
||||
return new ParameterizedType() {
|
||||
@Override
|
||||
public Type[] getActualTypeArguments()
|
||||
{
|
||||
return actuals;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getRawType()
|
||||
{
|
||||
return param.getRawType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getOwnerType()
|
||||
{
|
||||
return param.getOwnerType();
|
||||
}
|
||||
};
|
||||
}
|
||||
else if (type instanceof GenericArrayType)
|
||||
{
|
||||
GenericArrayType arrayType = (GenericArrayType)type;
|
||||
final Type componentType = resolveTypeVariables(root, arrayType.getGenericComponentType());
|
||||
if (componentType == null) return type;
|
||||
return new GenericArrayType()
|
||||
{
|
||||
@Override
|
||||
public Type getGenericComponentType()
|
||||
{
|
||||
return componentType;
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds an actual value of a type variable. The method looks in a class hierarchy for a class defining the variable
|
||||
* and returns the value if present.
|
||||
*
|
||||
* @param root
|
||||
* @param typeVariable
|
||||
* @return actual type of the type variable
|
||||
*/
|
||||
public static Type resolveTypeVariable(Class<?> root, TypeVariable<?> typeVariable)
|
||||
{
|
||||
if (typeVariable.getGenericDeclaration() instanceof Class<?>)
|
||||
{
|
||||
Class<?> classDeclaringTypeVariable = (Class<?>) typeVariable.getGenericDeclaration();
|
||||
Type[] types = findParameterizedTypes(root, classDeclaringTypeVariable);
|
||||
if (types == null) return null;
|
||||
for (int i = 0; i < types.length; i++)
|
||||
{
|
||||
TypeVariable<?> tv = classDeclaringTypeVariable.getTypeParameters()[i];
|
||||
if (tv.equals(typeVariable))
|
||||
{
|
||||
return types[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a class and an interfaces, go through the class hierarchy to find the interface and return its type arguments.
|
||||
*
|
||||
* @param classToSearch
|
||||
* @param interfaceToFind
|
||||
* @return type arguments of the interface
|
||||
*/
|
||||
public static Type[] getActualTypeArgumentsOfAnInterface(Class<?> classToSearch, Class<?> interfaceToFind)
|
||||
{
|
||||
Type[] types = findParameterizedTypes(classToSearch, interfaceToFind);
|
||||
if (types == null) throw new RuntimeException("Unable to find type arguments");
|
||||
return types;
|
||||
}
|
||||
|
||||
private static final Type[] EMPTY_TYPE_ARRAY = {};
|
||||
|
||||
/**
|
||||
* Search for the given interface or class within the root's class/interface hierarchy.
|
||||
* If the searched for class/interface is a generic return an array of real types that fill it out.
|
||||
*
|
||||
* @param root
|
||||
* @param searchedFor
|
||||
* @return
|
||||
*/
|
||||
public static Type[] findParameterizedTypes(Class<?> root, Class<?> searchedFor)
|
||||
{
|
||||
if (searchedFor.isInterface())
|
||||
{
|
||||
return findInterfaceParameterizedTypes(root, null, searchedFor);
|
||||
}
|
||||
return findClassParameterizedTypes(root, null, searchedFor);
|
||||
}
|
||||
|
||||
public static Type[] findClassParameterizedTypes(Class<?> root, ParameterizedType rootType, Class<?> searchedForClass)
|
||||
{
|
||||
if (Object.class.equals(root)) return null;
|
||||
|
||||
Map<String, Type> typeVarMap = populateParameterizedMap(root, rootType);
|
||||
|
||||
Class<?> superclass = root.getSuperclass();
|
||||
Type genericSuper = root.getGenericSuperclass();
|
||||
|
||||
if (superclass.equals(searchedForClass))
|
||||
{
|
||||
return extractTypes(typeVarMap, genericSuper);
|
||||
}
|
||||
|
||||
|
||||
if (genericSuper instanceof ParameterizedType)
|
||||
{
|
||||
ParameterizedType intfParam = (ParameterizedType) genericSuper;
|
||||
Type[] types = findClassParameterizedTypes(superclass, intfParam, searchedForClass);
|
||||
if (types != null)
|
||||
{
|
||||
return extractTypeVariables(typeVarMap, types);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Type[] types = findClassParameterizedTypes(superclass, null, searchedForClass);
|
||||
if (types != null)
|
||||
{
|
||||
return types;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Map<String, Type> populateParameterizedMap(Class<?> root, ParameterizedType rootType)
|
||||
{
|
||||
Map<String, Type> typeVarMap = new HashMap<String, Type>();
|
||||
if (rootType != null)
|
||||
{
|
||||
TypeVariable<? extends Class<?>>[] vars = root.getTypeParameters();
|
||||
for (int i = 0; i < vars.length; i++)
|
||||
{
|
||||
typeVarMap.put(vars[i].getName(), rootType.getActualTypeArguments()[i]);
|
||||
}
|
||||
}
|
||||
return typeVarMap;
|
||||
}
|
||||
|
||||
|
||||
public static Type[] findInterfaceParameterizedTypes(Class<?> root, ParameterizedType rootType, Class<?> searchedForInterface)
|
||||
{
|
||||
Map<String, Type> typeVarMap = populateParameterizedMap(root, rootType);
|
||||
|
||||
for (int i = 0; i < root.getInterfaces().length; i++)
|
||||
{
|
||||
Class<?> sub = root.getInterfaces()[i];
|
||||
Type genericSub = root.getGenericInterfaces()[i];
|
||||
if (sub.equals(searchedForInterface))
|
||||
{
|
||||
return extractTypes(typeVarMap, genericSub);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < root.getInterfaces().length; i++)
|
||||
{
|
||||
Type genericSub = root.getGenericInterfaces()[i];
|
||||
Class<?> sub = root.getInterfaces()[i];
|
||||
|
||||
Type[] types = recurseSuperclassForInterface(searchedForInterface, typeVarMap, genericSub, sub);
|
||||
if (types != null) return types;
|
||||
}
|
||||
if (root.isInterface()) return null;
|
||||
|
||||
Class<?> superclass = root.getSuperclass();
|
||||
Type genericSuper = root.getGenericSuperclass();
|
||||
|
||||
|
||||
return recurseSuperclassForInterface(searchedForInterface, typeVarMap, genericSuper, superclass);
|
||||
}
|
||||
|
||||
private static Type[] recurseSuperclassForInterface(Class<?> searchedForInterface, Map<String, Type> typeVarMap, Type genericSub, Class<?> sub)
|
||||
{
|
||||
if (genericSub instanceof ParameterizedType)
|
||||
{
|
||||
ParameterizedType intfParam = (ParameterizedType) genericSub;
|
||||
Type[] types = findInterfaceParameterizedTypes(sub, intfParam, searchedForInterface);
|
||||
if (types != null)
|
||||
{
|
||||
return extractTypeVariables(typeVarMap, types);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Type[] types = findInterfaceParameterizedTypes(sub, null, searchedForInterface);
|
||||
if (types != null)
|
||||
{
|
||||
return types;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Type[] extractTypeVariables(Map<String, Type> typeVarMap, Type[] types)
|
||||
{
|
||||
for (int j = 0; j < types.length; j++)
|
||||
{
|
||||
if (types[j] instanceof TypeVariable)
|
||||
{
|
||||
TypeVariable tv = (TypeVariable) types[j];
|
||||
types[j] = typeVarMap.get(tv.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
types[j] = types[j];
|
||||
}
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
private static Type[] extractTypes(Map<String, Type> typeVarMap, Type genericSub)
|
||||
{
|
||||
if (genericSub instanceof ParameterizedType)
|
||||
{
|
||||
ParameterizedType param = (ParameterizedType) genericSub;
|
||||
Type[] types = param.getActualTypeArguments();
|
||||
Type[] returnTypes = new Type[types.length];
|
||||
System.arraycopy(types, 0, returnTypes, 0, types.length);
|
||||
extractTypeVariables(typeVarMap, returnTypes);
|
||||
return returnTypes;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EMPTY_TYPE_ARRAY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the parameterized type of fromInterface
|
||||
* that object implements and sees if it is assignable from type.
|
||||
*
|
||||
* @param type
|
||||
* @param object
|
||||
* @param fromInterface
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> boolean supports(Class<T> type, Object object, Class<?> fromInterface) {
|
||||
Type providerType = getActualTypeArgumentsOfAnInterface(object.getClass(), fromInterface)[0];
|
||||
Class providerClass = getRawType(providerType);
|
||||
return type.isAssignableFrom(providerClass);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -147,6 +147,15 @@ public class JpaUserFederatedStorageProvider implements
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUsersByUserAttribute(RealmModel realm, String name, String value) {
|
||||
TypedQuery<String> query = em.createNamedQuery("getFederatedAttributesByNameAndValue", String.class)
|
||||
.setParameter("realmId", realm.getId())
|
||||
.setParameter("name", name)
|
||||
.setParameter("value", value);
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserByFederatedIdentity(FederatedIdentityModel link, RealmModel realm) {
|
||||
TypedQuery<String> query = em.createNamedQuery("findUserByBrokerLinkAndRealm", String.class)
|
||||
|
@ -508,6 +517,15 @@ public class JpaUserFederatedStorageProvider implements
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMembership(RealmModel realm, GroupModel group, int firstResult, int max) {
|
||||
TypedQuery<String> query = em.createNamedQuery("fedgroupMembership", String.class)
|
||||
.setParameter("realmId", realm.getId())
|
||||
.setParameter("groupId", group.getId());
|
||||
query.setFirstResult(firstResult);
|
||||
query.setMaxResults(max);
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRequiredActions(RealmModel realm, UserModel user) {
|
||||
|
@ -689,7 +707,7 @@ public class JpaUserFederatedStorageProvider implements
|
|||
.setParameter("userId", user.getId())
|
||||
.setParameter("realmId", realm.getId())
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("getFederatedUserRequiredActionsByUser")
|
||||
em.createNamedQuery("deleteFederatedUserRequiredActionsByUser")
|
||||
.setParameter("userId", user.getId())
|
||||
.setParameter("realmId", realm.getId())
|
||||
.executeUpdate();
|
||||
|
|
|
@ -32,7 +32,7 @@ import javax.persistence.Table;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="getFederatedAttributesByNameAndValue", query="select attr from FederatedUserAttributeEntity attr where attr.name = :name and attr.value = :value and attr.realmId=:realmId"),
|
||||
@NamedQuery(name="getFederatedAttributesByNameAndValue", query="select attr.userId from FederatedUserAttributeEntity attr where attr.name = :name and attr.value = :value and attr.realmId=:realmId"),
|
||||
@NamedQuery(name="getFederatedAttributesByUser", query="select attr from FederatedUserAttributeEntity attr where attr.userId = :userId and attr.realmId=:realmId"),
|
||||
@NamedQuery(name="deleteUserFederatedAttributesByUser", query="delete from FederatedUserAttributeEntity attr where attr.userId = :userId and attr.realmId=:realmId"),
|
||||
@NamedQuery(name="deleteUserFederatedAttributesByUserAndName", query="delete from FederatedUserAttributeEntity attr where attr.userId = :userId and attr.name=:name and attr.realmId=:realmId"),
|
||||
|
|
|
@ -35,7 +35,7 @@ import java.io.Serializable;
|
|||
@NamedQueries({
|
||||
@NamedQuery(name="feduserMemberOf", query="select m from FederatedUserGroupMembershipEntity m where m.userId = :userId and m.groupId = :groupId"),
|
||||
@NamedQuery(name="feduserGroupMembership", query="select m from FederatedUserGroupMembershipEntity m where m.userId = :userId"),
|
||||
@NamedQuery(name="fedgroupMembership", query="select g.userId from FederatedUserGroupMembershipEntity g where g.groupId = :groupId"),
|
||||
@NamedQuery(name="fedgroupMembership", query="select g.userId from FederatedUserGroupMembershipEntity g where g.groupId = :groupId and g.realmId = :realmId"),
|
||||
@NamedQuery(name="feduserGroupIds", query="select m.groupId from FederatedUserGroupMembershipEntity m where m.userId = :userId"),
|
||||
@NamedQuery(name="deleteFederatedUserGroupMembershipByRealm", query="delete from FederatedUserGroupMembershipEntity mapping where mapping.realmId=:realmId"),
|
||||
@NamedQuery(name="deleteFederatedUserGroupMembershipByStorageProvider", query="delete from FederatedUserGroupMembershipEntity e where e.storageProviderId=:storageProviderId"),
|
||||
|
|
|
@ -37,6 +37,7 @@ import java.io.Serializable;
|
|||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="getFederatedUserRequiredActionsByUser", query="select action from FederatedUserRequiredActionEntity action where action.userId = :userId and action.realmId=:realmId"),
|
||||
@NamedQuery(name="deleteFederatedUserRequiredActionsByUser", query="delete from FederatedUserRequiredActionEntity action where action.realmId=:realmId and action.userId = :userId"),
|
||||
@NamedQuery(name="deleteFederatedUserRequiredActionsByRealm", query="delete from FederatedUserRequiredActionEntity action where action.realmId=:realmId"),
|
||||
@NamedQuery(name="deleteFederatedUserRequiredActionsByStorageProvider", query="delete from FederatedUserRequiredActionEntity e where e.storageProviderId=:storageProviderId"),
|
||||
@NamedQuery(name="deleteFederatedUserRequiredActionsByRealmAndLink", query="delete from FederatedUserRequiredActionEntity action where action.userId IN (select u.id from UserEntity u where u.realmId=:realmId and u.federationLink=:link)")
|
||||
|
|
|
@ -26,8 +26,7 @@ import java.util.Set;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface StorageProviderFactory extends ProviderFactory<StorageProvider> {
|
||||
boolean supports(Class<?> type);
|
||||
public interface StorageProviderFactory<T extends StorageProvider> extends ProviderFactory<StorageProvider> {
|
||||
/**
|
||||
* called per Keycloak transaction.
|
||||
*
|
||||
|
@ -35,14 +34,7 @@ public interface StorageProviderFactory extends ProviderFactory<StorageProvider>
|
|||
* @param model
|
||||
* @return
|
||||
*/
|
||||
StorageProvider getInstance(KeycloakSession session, StorageProviderModel model);
|
||||
|
||||
/**
|
||||
* Config options to display in generic admin console page for federated
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Set<String> getConfigurationOptions();
|
||||
T getInstance(KeycloakSession session, StorageProviderModel model);
|
||||
|
||||
/**
|
||||
* This is the name of the provider and will be showed in the admin console as an option.
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.keycloak.storage;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.util.reflections.Types;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.CredentialValidationOutput;
|
||||
import org.keycloak.models.FederatedIdentityModel;
|
||||
|
@ -42,6 +43,7 @@ import org.keycloak.models.utils.CredentialValidation;
|
|||
import org.keycloak.storage.federated.UserFederatedStorageProvider;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
@ -79,18 +81,20 @@ public class UserStorageManager implements UserProvider {
|
|||
protected <T> T getFirstStorageProvider(RealmModel realm, Class<T> type) {
|
||||
for (StorageProviderModel model : getStorageProviders(realm)) {
|
||||
StorageProviderFactory factory = (StorageProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(StorageProvider.class, model.getProviderName());
|
||||
if (factory.supports(type)) {
|
||||
|
||||
if (Types.supports(type, factory, StorageProviderFactory.class)) {
|
||||
return type.cast(factory.getInstance(session, model));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected <T> List<T> getStorageProviders(RealmModel realm, Class<T> type) {
|
||||
List<T> list = new LinkedList<>();
|
||||
for (StorageProviderModel model : getStorageProviders(realm)) {
|
||||
StorageProviderFactory factory = (StorageProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(StorageProvider.class, model.getProviderName());
|
||||
if (factory.supports(type)) {
|
||||
if (Types.supports(type, factory, StorageProviderFactory.class)) {
|
||||
list.add(type.cast(factory.getInstance(session, model)));
|
||||
}
|
||||
|
||||
|
@ -130,6 +134,7 @@ public class UserStorageManager implements UserProvider {
|
|||
|
||||
@Override
|
||||
public boolean removeUser(RealmModel realm, UserModel user) {
|
||||
getFederatedStorage().preRemove(realm, user);
|
||||
StorageId storageId = new StorageId(user.getId());
|
||||
if (storageId.getProviderId() == null) {
|
||||
return localStorage().removeUser(realm, user);
|
||||
|
@ -299,29 +304,33 @@ public class UserStorageManager implements UserProvider {
|
|||
return size;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface PaginatedQuery {
|
||||
List<UserModel> query(UserQueryProvider provider, int first, int max);
|
||||
List<UserModel> query(Object provider, int first, int max);
|
||||
}
|
||||
|
||||
protected List<UserModel> query(PaginatedQuery pagedQuery, RealmModel realm, int firstResult, int maxResults) {
|
||||
List<UserModel> results = new LinkedList<UserModel>();
|
||||
if (maxResults == 0) return results;
|
||||
if (maxResults == 0) return Collections.EMPTY_LIST;
|
||||
|
||||
|
||||
|
||||
List<UserQueryProvider> storageProviders = getStorageProviders(realm, UserQueryProvider.class);
|
||||
LinkedList<UserQueryProvider> providers = new LinkedList<>();
|
||||
if (providers.isEmpty()) {
|
||||
// we can skip rest of method if there are no storage providers
|
||||
if (storageProviders.isEmpty()) {
|
||||
return pagedQuery.query(localStorage(), firstResult, maxResults);
|
||||
}
|
||||
LinkedList<Object> providers = new LinkedList<>();
|
||||
List<UserModel> results = new LinkedList<UserModel>();
|
||||
providers.add(localStorage());
|
||||
providers.addAll(storageProviders);
|
||||
providers.add(getFederatedStorage());
|
||||
|
||||
int leftToRead = maxResults;
|
||||
int leftToFirstResult = firstResult;
|
||||
|
||||
Iterator<UserQueryProvider> it = providers.iterator();
|
||||
Iterator<Object> it = providers.iterator();
|
||||
while (it.hasNext() && leftToRead != 0) {
|
||||
UserQueryProvider provider = it.next();
|
||||
Object provider = it.next();
|
||||
boolean exhausted = false;
|
||||
int index = 0;
|
||||
if (leftToFirstResult > 0) {
|
||||
|
@ -341,20 +350,22 @@ public class UserStorageManager implements UserProvider {
|
|||
results.addAll(tmp);
|
||||
if (leftToRead > 0) leftToRead -= tmp.size();
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> getUsers(final RealmModel realm, int firstResult, int maxResults, final boolean includeServiceAccounts) {
|
||||
return query(new PaginatedQuery() {
|
||||
@Override
|
||||
public List<UserModel> query(UserQueryProvider provider, int first, int max) {
|
||||
if (provider instanceof UserProvider) { // it is local storage
|
||||
return ((UserProvider)provider).getUsers(realm, first, max, includeServiceAccounts);
|
||||
}
|
||||
return provider.getUsers(realm, first, max);
|
||||
return query((provider, first, max) -> {
|
||||
if (provider instanceof UserProvider) { // it is local storage
|
||||
return ((UserProvider) provider).getUsers(realm, first, max, includeServiceAccounts);
|
||||
} else if (provider instanceof UserQueryProvider) {
|
||||
return ((UserQueryProvider)provider).getUsers(realm, first, max);
|
||||
|
||||
}
|
||||
}, realm, firstResult, maxResults);
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
, realm, firstResult, maxResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -363,12 +374,13 @@ public class UserStorageManager implements UserProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> searchForUser(final String search, final RealmModel realm, int firstResult, int maxResults) {
|
||||
return query(new PaginatedQuery() {
|
||||
@Override
|
||||
public List<UserModel> query(UserQueryProvider provider, int first, int max) {
|
||||
return provider.searchForUser(search, realm, first, max);
|
||||
public List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
|
||||
return query((provider, first, max) -> {
|
||||
if (provider instanceof UserQueryProvider) {
|
||||
return ((UserQueryProvider)provider).searchForUser(search, realm, first, max);
|
||||
|
||||
}
|
||||
return Collections.EMPTY_LIST;
|
||||
}, realm, firstResult, maxResults);
|
||||
}
|
||||
|
||||
|
@ -378,23 +390,36 @@ public class UserStorageManager implements UserProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> searchForUserByAttributes(final Map<String, String> attributes, final RealmModel realm, int firstResult, int maxResults) {
|
||||
return query(new PaginatedQuery() {
|
||||
@Override
|
||||
public List<UserModel> query(UserQueryProvider provider, int first, int max) {
|
||||
return provider.searchForUserByAttributes(attributes, realm, first, max);
|
||||
public List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm, int firstResult, int maxResults) {
|
||||
return query((provider, first, max) -> {
|
||||
if (provider instanceof UserQueryProvider) {
|
||||
return ((UserQueryProvider)provider).searchForUserByAttributes(attributes, realm, first, max);
|
||||
|
||||
}
|
||||
}, realm, firstResult, maxResults);
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
, realm, firstResult, maxResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> searchForUserByUserAttribute(final String attrName, final String attrValue, RealmModel realm) {
|
||||
return query(new PaginatedQuery() {
|
||||
@Override
|
||||
public List<UserModel> query(UserQueryProvider provider, int first, int max) {
|
||||
return provider.searchForUserByUserAttribute(attrName, attrValue, realm);
|
||||
public List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
|
||||
List<UserModel> results = query((provider, first, max) -> {
|
||||
if (provider instanceof UserQueryProvider) {
|
||||
return ((UserQueryProvider)provider).searchForUserByUserAttribute(attrName, attrValue, realm);
|
||||
|
||||
} else if (provider instanceof UserFederatedStorageProvider) {
|
||||
List<String> ids = ((UserFederatedStorageProvider)provider).getUsersByUserAttribute(realm, attrName, attrValue);
|
||||
List<UserModel> rs = new LinkedList<>();
|
||||
for (String id : ids) {
|
||||
UserModel user = getUserById(id, realm);
|
||||
if (user != null) rs.add(user);
|
||||
}
|
||||
return rs;
|
||||
|
||||
}
|
||||
return Collections.EMPTY_LIST;
|
||||
}, realm,0, Integer.MAX_VALUE - 1);
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -432,12 +457,23 @@ public class UserStorageManager implements UserProvider {
|
|||
|
||||
@Override
|
||||
public List<UserModel> getGroupMembers(final RealmModel realm, final GroupModel group, int firstResult, int maxResults) {
|
||||
return query(new PaginatedQuery() {
|
||||
@Override
|
||||
public List<UserModel> query(UserQueryProvider provider, int first, int max) {
|
||||
return provider.getGroupMembers(realm, group, first, max);
|
||||
List<UserModel> results = query((provider, first, max) -> {
|
||||
if (provider instanceof UserQueryProvider) {
|
||||
return ((UserQueryProvider)provider).getGroupMembers(realm, group, first, max);
|
||||
|
||||
} else if (provider instanceof UserFederatedStorageProvider) {
|
||||
List<String> ids = ((UserFederatedStorageProvider)provider).getMembership(realm, group, first, max);
|
||||
List<UserModel> rs = new LinkedList<UserModel>();
|
||||
for (String id : ids) {
|
||||
UserModel user = getUserById(id, realm);
|
||||
if (user != null) rs.add(user);
|
||||
}
|
||||
return rs;
|
||||
|
||||
}
|
||||
return Collections.EMPTY_LIST;
|
||||
}, realm, firstResult, maxResults);
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -402,4 +402,19 @@ public abstract class AbstractUserAdapter implements UserModel {
|
|||
throw new ReadOnlyException("user is read only for this update");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || !(o instanceof UserModel)) return false;
|
||||
|
||||
UserModel that = (UserModel) o;
|
||||
return that.getId().equals(getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getId().hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -416,4 +416,19 @@ public abstract class AbstractUserAdapterFederatedStorage implements UserModel {
|
|||
getFederatedStorage().updateCredential(realm, this, cred);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || !(o instanceof UserModel)) return false;
|
||||
|
||||
UserModel that = (UserModel) o;
|
||||
return that.getId().equals(getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getId().hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.keycloak.models.UserModel;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -32,4 +33,5 @@ public interface UserAttributeFederatedStorage {
|
|||
void setAttribute(RealmModel realm, UserModel user, String name, List<String> values);
|
||||
void removeAttribute(RealmModel realm, UserModel user, String name);
|
||||
MultivaluedHashMap<String, String> getAttributes(RealmModel realm, UserModel user);
|
||||
List<String> getUsersByUserAttribute(RealmModel realm, String name, String value);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.keycloak.models.GroupModel;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -28,9 +29,8 @@ import java.util.Set;
|
|||
*/
|
||||
public interface UserGroupMembershipFederatedStorage {
|
||||
Set<GroupModel> getGroups(RealmModel realm, UserModel user);
|
||||
|
||||
void joinGroup(RealmModel realm,UserModel user, GroupModel group);
|
||||
|
||||
void leaveGroup(RealmModel realm,UserModel user, GroupModel group);
|
||||
List<String> getMembership(RealmModel realm, GroupModel group, int firstResult, int max);
|
||||
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ import org.keycloak.testsuite.rule.WebResource;
|
|||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -146,4 +148,89 @@ public class UserFederationStorageTest {
|
|||
loginSuccessAndLogout("thor", "lightning");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuery() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
|
||||
// Test paging
|
||||
List<UserModel> localUsers = session.userLocalStorage().getUsers(realm, false);
|
||||
Set<UserModel> queried = new HashSet<>();
|
||||
// tests assumes that local storage is queried first
|
||||
int first = localUsers.size();
|
||||
while (queried.size() < 8) {
|
||||
List<UserModel> results = session.users().getUsers(realm, first, 3);
|
||||
if (results.size() == 0) break;
|
||||
first += results.size();
|
||||
queried.addAll(results);
|
||||
|
||||
}
|
||||
Set<String> usernames = new HashSet<>();
|
||||
for (UserModel user : queried) {
|
||||
usernames.add(user.getUsername());
|
||||
System.out.println(user.getUsername());
|
||||
|
||||
}
|
||||
Assert.assertEquals(8, queried.size());
|
||||
Assert.assertTrue(usernames.contains("thor"));
|
||||
Assert.assertTrue(usernames.contains("zeus"));
|
||||
Assert.assertTrue(usernames.contains("apollo"));
|
||||
Assert.assertTrue(usernames.contains("perseus"));
|
||||
Assert.assertTrue(usernames.contains("tbrady"));
|
||||
Assert.assertTrue(usernames.contains("rob"));
|
||||
Assert.assertTrue(usernames.contains("jules"));
|
||||
Assert.assertTrue(usernames.contains("danny"));
|
||||
|
||||
// test searchForUser
|
||||
List<UserModel> users = session.users().searchForUser("tbrady", realm);
|
||||
Assert.assertTrue(users.size() == 1);
|
||||
Assert.assertTrue(users.get(0).getUsername().equals("tbrady"));
|
||||
|
||||
// test getGroupMembers()
|
||||
GroupModel gods = realm.createGroup("gods");
|
||||
UserModel user = null;
|
||||
user = session.users().getUserByUsername("apollo", realm);
|
||||
user.joinGroup(gods);
|
||||
user = session.users().getUserByUsername("zeus", realm);
|
||||
user.joinGroup(gods);
|
||||
user = session.users().getUserByUsername("thor", realm);
|
||||
user.joinGroup(gods);
|
||||
queried.clear();
|
||||
usernames.clear();
|
||||
|
||||
first = 0;
|
||||
while (queried.size() < 8) {
|
||||
List<UserModel> results = session.users().getGroupMembers(realm, gods, first, 1);
|
||||
if (results.size() == 0) break;
|
||||
first += results.size();
|
||||
queried.addAll(results);
|
||||
|
||||
}
|
||||
for (UserModel u : queried) {
|
||||
usernames.add(u.getUsername());
|
||||
System.out.println(u.getUsername());
|
||||
|
||||
}
|
||||
Assert.assertEquals(3, queried.size());
|
||||
Assert.assertTrue(usernames.contains("apollo"));
|
||||
Assert.assertTrue(usernames.contains("zeus"));
|
||||
Assert.assertTrue(usernames.contains("thor"));
|
||||
|
||||
// search by single attribute
|
||||
System.out.println("search by single attribute");
|
||||
user = session.users().getUserByUsername("thor", realm);
|
||||
user.setSingleAttribute("weapon", "hammer");
|
||||
|
||||
users = session.users().searchForUserByUserAttribute("weapon", "hammer", realm);
|
||||
for (UserModel u : users) {
|
||||
System.out.println(u.getUsername());
|
||||
|
||||
}
|
||||
Assert.assertEquals(1, users.size());
|
||||
Assert.assertEquals("thor", users.get(0).getUsername());
|
||||
|
||||
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,15 +30,19 @@ import org.keycloak.storage.adapter.AbstractUserAdapterFederatedStorage;
|
|||
import org.keycloak.storage.federated.UserFederatedStorageProvider;
|
||||
import org.keycloak.storage.user.UserCredentialValidatorProvider;
|
||||
import org.keycloak.storage.user.UserLookupProvider;
|
||||
import org.keycloak.storage.user.UserQueryProvider;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UserPropertyFileStorage implements UserLookupProvider, StorageProvider, UserCredentialValidatorProvider {
|
||||
public class UserPropertyFileStorage implements UserLookupProvider, StorageProvider, UserCredentialValidatorProvider, UserQueryProvider {
|
||||
|
||||
protected Properties userPasswords;
|
||||
protected StorageProviderModel model;
|
||||
|
@ -128,6 +132,85 @@ public class UserPropertyFileStorage implements UserLookupProvider, StorageProvi
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUsersCount(RealmModel realm) {
|
||||
return userPasswords.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> getUsers(RealmModel realm) {
|
||||
List<UserModel> users = new LinkedList<>();
|
||||
for (Object username : userPasswords.keySet()) {
|
||||
users.add(createUser(realm, (String)username));
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
|
||||
if (maxResults == 0) return Collections.EMPTY_LIST;
|
||||
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
|
||||
public List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
|
||||
if (maxResults == 0) return Collections.EMPTY_LIST;
|
||||
List<UserModel> users = new LinkedList<>();
|
||||
int count = 0;
|
||||
for (Object un : userPasswords.keySet()) {
|
||||
String username = (String)un;
|
||||
if (username.contains(search)) {
|
||||
if (count++ < firstResult) {
|
||||
continue;
|
||||
}
|
||||
users.add(createUser(realm, username));
|
||||
if (users.size() + 1 > maxResults) break;
|
||||
}
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm, int firstResult, int maxResults) {
|
||||
if (attributes.size() != 1) return Collections.EMPTY_LIST;
|
||||
String username = attributes.get(UserModel.USERNAME);
|
||||
if (username == null) return Collections.EMPTY_LIST;
|
||||
return searchForUser(username, realm, firstResult, maxResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> getGroupMembers(RealmModel realm, GroupModel group) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> searchForUser(String search, RealmModel realm) {
|
||||
return getUsers(realm, 0, Integer.MAX_VALUE - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
|
|
|
@ -34,18 +34,13 @@ import java.util.Set;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UserPropertyFileStorageFactory implements StorageProviderFactory {
|
||||
public class UserPropertyFileStorageFactory implements StorageProviderFactory<UserPropertyFileStorage> {
|
||||
|
||||
|
||||
public static final String PROVIDER_ID = "user-password-props";
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> type) {
|
||||
return type.isAssignableFrom(UserPropertyFileStorage.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageProvider getInstance(KeycloakSession session, StorageProviderModel model) {
|
||||
public UserPropertyFileStorage getInstance(KeycloakSession session, StorageProviderModel model) {
|
||||
Properties props = new Properties();
|
||||
try {
|
||||
props.load(getClass().getResourceAsStream(model.getConfig().get("property.file")));
|
||||
|
@ -55,11 +50,6 @@ public class UserPropertyFileStorageFactory implements StorageProviderFactory {
|
|||
return new UserPropertyFileStorage(session, model, props);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getConfigurationOptions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return PROVIDER_ID;
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
tbrady=goat
|
||||
tbrady=goat
|
||||
rob=pw
|
||||
jules=pw
|
||||
danny=pw
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
thor=hammer
|
||||
thor=hammer
|
||||
zeus=pw
|
||||
apollo=pw
|
||||
perseus=pw
|
Loading…
Reference in a new issue