fix: improve group matching (#25627)

closes #25451

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
This commit is contained in:
Steven Hawkins 2023-12-18 05:46:02 -05:00 committed by GitHub
parent cd154cf318
commit ec28b68554
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 8 deletions

View file

@ -29,7 +29,7 @@ import static org.keycloak.client.admin.cli.util.HttpUtil.getIdForType;
public class GroupOperations {
public static String getIdFromName(String rootUrl, String realm, String auth, String groupname) {
return getIdForType(rootUrl, realm, auth, "groups", "name", groupname, "name");
return getIdForType(rootUrl, realm, auth, "groups", "search", groupname, "name", () -> new String[] { "exact", "true" });
}
public static String getIdFromPath(String rootUrl, String realm, String auth, String path) {

View file

@ -462,21 +462,24 @@ public class HttpUtil {
resourceUrl = HttpUtil.addQueryParamsToUri(resourceUrl, attrName, attrValue);
resourceUrl = HttpUtil.addQueryParamsToUri(resourceUrl, defaultParams);
List<ObjectNode> users = doGetJSON(RoleOperations.LIST_OF_NODES.class, resourceUrl, auth);
List<ObjectNode> results = doGetJSON(RoleOperations.LIST_OF_NODES.class, resourceUrl, auth);
ObjectNode user;
ObjectNode match;
try {
user = new LocalSearch(users).exactMatchOne(attrValue, inputAttrName);
match = new LocalSearch(results).exactMatchOne(attrValue, inputAttrName);
} catch (Exception e) {
throw new RuntimeException("Multiple " + resourceEndpoint + " found for " + attrName + ": " + attrValue, e);
throw new RuntimeException("Multiple " + resourceEndpoint + " found for " + inputAttrName + ": " + attrValue, e);
}
String typeName = singularize(resourceEndpoint);
if (user == null) {
throw new RuntimeException(capitalize(typeName) + " not found for " + attrName + ": " + attrValue);
if (match == null) {
if (results.size() > 1) {
throw new RuntimeException("Some matches, but not an exact match, found for " + capitalize(typeName) + " with " + inputAttrName + ": " + attrValue + ". Try using a more unique search, such as an id.");
}
throw new RuntimeException(capitalize(typeName) + " not found for " + inputAttrName + ": " + attrValue);
}
JsonNode attr = user.get(returnAttrName);
JsonNode attr = match.get(returnAttrName);
if (attr == null) {
throw new RuntimeException("Returned " + typeName + " info has no '" + returnAttrName + "' attribute");
}

View file

@ -617,6 +617,28 @@ public class KcAdmTest extends AbstractAdmCliTest {
KcAdmExec.execute("create users -r demorealm -s username=onemoretestuser");
KcAdmExec exec = execute("add-roles --uusername=testuser --rolename offline_access --target-realm=demorealm");
Assert.assertEquals(0, exec.exitCode());
exec = execute("add-roles --uusername=anothertestuser --rolename offline_access --target-realm=demorealm");
Assert.assertEquals(0, exec.exitCode());
exec = execute("add-roles --uusername=onemoretestuser --rolename offline_access --target-realm=demorealm");
Assert.assertEquals(0, exec.exitCode());
}
@Test
public void testGetGroupNameExact() {
KcAdmExec.execute("config credentials --server " + serverUrl + " --realm master --user admin --password admin");
KcAdmExec.execute("create realms -s realm=demorealm -s enabled=true");
KcAdmExec.execute("create role -r demorealm -s name=testrole");
KcAdmExec.execute("create groups -r demorealm -s name=test");
KcAdmExec.execute("create groups -r demorealm -s name=anothertest");
KcAdmExec.execute("create groups -r demorealm -s name=onemoretest");
KcAdmExec exec = execute("get-roles -r demorealm --gname test");
Assert.assertEquals(exec.stderrString(), 0, exec.exitCode());
exec = execute("get-roles -r demorealm --gname anothertest");
Assert.assertEquals(exec.stderrString(), 0, exec.exitCode());
exec = execute("get-roles -r demorealm --gname onemoretest");
Assert.assertEquals(exec.stderrString(), 0, exec.exitCode());
exec = execute("get-roles -r demorealm --gname not_there");
Assert.assertEquals(1, exec.exitCode());
}
@Test