fix: updating docs around -q parameter (#29151)
closes: #27877 Signed-off-by: Steve Hawkins <shawkins@redhat.com>
This commit is contained in:
parent
f3227c325a
commit
3b1ca46be2
8 changed files with 27 additions and 19 deletions
|
@ -1031,15 +1031,15 @@ You can filter users by `username`, `firstName`, `lastName`, or `email`.
|
|||
For example:
|
||||
[options="nowrap"]
|
||||
----
|
||||
$ kcadm.sh get users -r demorealm -q email=google.com
|
||||
$ kcadm.sh get users -r demorealm -q username=testuser
|
||||
$ kcadm.sh get users -r demorealm -q q=email:google.com
|
||||
$ kcadm.sh get users -r demorealm -q q=username:testuser
|
||||
----
|
||||
[NOTE]
|
||||
====
|
||||
Filtering does not use exact matching. This example matches the value of the `username` attribute against the `\*testuser*` pattern.
|
||||
====
|
||||
|
||||
You can filter across multiple attributes by specifying multiple `-q` options. {project_name} returns users that match the condition for all the attributes only.
|
||||
For clients, groups, and users you can filter across multiple attributes by specifying a more complex `q` query parameter. you may use something like -q q="field1:value1 field2:value2". {project_name} returns users that match the condition for all the attributes only.
|
||||
|
||||
[discrete]
|
||||
==== Getting a specific user
|
||||
|
|
|
@ -113,7 +113,7 @@ public abstract class AbstractRequestCmd extends AbstractAuthOptionsCmd {
|
|||
@ArgGroup(exclusive = true, multiplicity = "0..*")
|
||||
List<AttributeOperations> rawAttributeOperations = new ArrayList<>();
|
||||
|
||||
@Option(names = {"-q", "--query"}, description = "Add to request URI a NAME query parameter with value VALUE")
|
||||
@Option(names = {"-q", "--query"}, description = "Add to request URI a NAME query parameter with value VALUE, for example --query q=username:admin")
|
||||
List<String> rawFilters = new LinkedList<>();
|
||||
|
||||
@Parameters(arity = "0..1")
|
||||
|
@ -142,12 +142,7 @@ public abstract class AbstractRequestCmd extends AbstractAuthOptionsCmd {
|
|||
}
|
||||
|
||||
for (String arg : rawFilters) {
|
||||
String[] keyVal;
|
||||
if (arg.indexOf("=") == -1) {
|
||||
keyVal = new String[] {"", arg};
|
||||
} else {
|
||||
keyVal = parseKeyVal(arg);
|
||||
}
|
||||
String[] keyVal = parseKeyVal(arg);
|
||||
filter.put(keyVal[0], keyVal[1]);
|
||||
}
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ public class CreateCmd extends AbstractRequestCmd {
|
|||
out.println(" -d, --delete NAME Remove a specific attribute NAME from JSON request body");
|
||||
out.println(" -f, --file FILENAME Read object from file or standard input if FILENAME is set to '-'");
|
||||
out.println(" -b, --body CONTENT Content to be sent as-is or used as a JSON object template");
|
||||
out.println(" -q, --query NAME=VALUE Add to request URI a NAME query parameter with value VALUE");
|
||||
out.println(" -q, --query NAME=VALUE Add to request URI a NAME query parameter with value VALUE, for example --query q=username:admin");
|
||||
out.println(" -h, --header NAME=VALUE Set request header NAME to VALUE");
|
||||
out.println();
|
||||
out.println(" -H, --print-headers Print response headers");
|
||||
|
|
|
@ -74,7 +74,7 @@ public class DeleteCmd extends CreateCmd {
|
|||
out.println(" -d, --delete NAME Remove a specific attribute NAME from JSON request body");
|
||||
out.println(" -f, --file FILENAME Send a body with request - read object from file or standard input if FILENAME is set to '-'");
|
||||
out.println(" -b, --body CONTENT Content to be sent as-is or used as a JSON object template");
|
||||
out.println(" -q, --query NAME=VALUE Add to request URI a NAME query parameter with value VALUE");
|
||||
out.println(" -q, --query NAME=VALUE Add to request URI a NAME query parameter with value VALUE, for example --query q=username:admin");
|
||||
out.println(" -h, --header NAME=VALUE Set request header NAME to VALUE");
|
||||
out.println();
|
||||
out.println(" -H, --print-headers Print response headers");
|
||||
|
|
|
@ -106,7 +106,7 @@ public class GetCmd extends AbstractRequestCmd {
|
|||
out.println(" realms, users, roles, groups, clients, keys, serverinfo, components ...");
|
||||
out.println(" If it starts with 'http://' then it will be used as target resource url");
|
||||
out.println(" -r, --target-realm REALM Target realm to issue requests against if not the one authenticated against");
|
||||
out.println(" -q, --query NAME=VALUE Add to request URI a NAME query parameter with value VALUE");
|
||||
out.println(" -q, --query NAME=VALUE Add to request URI a NAME query parameter with value VALUE, for example --query q=username:admin");
|
||||
out.println(" -h, --header NAME=VALUE Set request header NAME to VALUE");
|
||||
out.println(" -o, --offset OFFSET Set paging offset - adds a query parameter 'first' which some endpoints recognize");
|
||||
out.println(" -l, --limit LIMIT Set limit to number of items in result - adds a query parameter 'max' ");
|
||||
|
@ -164,7 +164,7 @@ public class GetCmd extends AbstractRequestCmd {
|
|||
out.println("Note: 'users' endpoint knows how to handle --offset and --limit. Most other endpoints don't.");
|
||||
out.println();
|
||||
out.println("Get all users whose 'username' matches '*test*' pattern, and 'email' matches '*@google.com*':");
|
||||
out.println(" " + PROMPT + " " + CMD + " get users -r demorealm -q username=test -q email=@google.com");
|
||||
out.println(" " + PROMPT + " " + CMD + " get users -r demorealm -q q=\"username:test email:@google.com\"");
|
||||
out.println();
|
||||
out.println("Note: it is the 'users' endpoint that interprets query parameters 'username', and 'email' in such a way that");
|
||||
out.println("it results in the described semantics. Another endpoint may provide a different semantics.");
|
||||
|
|
|
@ -117,7 +117,7 @@ public class UpdateCmd extends AbstractRequestCmd {
|
|||
out.println(" -d, --delete NAME Remove a specific attribute NAME from JSON request body");
|
||||
out.println(" -f, --file FILENAME Read object from file or standard input if FILENAME is set to '-'");
|
||||
out.println(" -b, --body CONTENT Content to be sent as-is or used as a JSON object template");
|
||||
out.println(" -q, --query NAME=VALUE Add to request URI a NAME query parameter with value VALUE");
|
||||
out.println(" -q, --query NAME=VALUE Add to request URI a NAME query parameter with value VALUE, for example --query q=username:admin");
|
||||
out.println(" -h, --header NAME=VALUE Set request header NAME to VALUE");
|
||||
out.println(" -m, --merge Merge new values with existing configuration on the server");
|
||||
out.println(" Merge is automatically enabled unless --file is specified");
|
||||
|
|
|
@ -314,7 +314,7 @@ public class HttpUtil {
|
|||
}
|
||||
query.append(params.getKey()).append("=").append(URLEncoder.encode(params.getValue(), "utf-8"));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to encode query params: " + params.getKey() + "=" + params.getValue());
|
||||
throw new IllegalArgumentException("Failed to encode query params: " + params.getKey() + "=" + params.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package org.keycloak.testsuite.cli.admin;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.client.cli.config.FileConfigHandler;
|
||||
|
@ -13,9 +11,14 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
|
||||
import static org.keycloak.testsuite.cli.KcAdmExec.execute;
|
||||
|
||||
|
@ -48,6 +51,16 @@ public class KcAdmSessionTest extends AbstractAdmCliTest {
|
|||
assertExitCodeAndStreamSizes(exe, 0, 1, 0);
|
||||
String userId = exe.stdoutLines().get(0);
|
||||
|
||||
exe = execute("get users --config '" + configFile.getName() + "' -r demorealm -q q=username:testuser");
|
||||
assertExitCodeAndStdErrSize(exe, 0, 0);
|
||||
String result = exe.stdoutString();
|
||||
assertTrue(result.contains(userId));
|
||||
|
||||
exe = execute("get users --config '" + configFile.getName() + "' -r demorealm -q q=username:non-existent");
|
||||
assertExitCodeAndStdErrSize(exe, 0, 0);
|
||||
String emptyResult = exe.stdoutString();
|
||||
assertFalse(emptyResult.contains(userId));
|
||||
|
||||
// add realm admin capabilities to user
|
||||
exe = execute("add-roles --config '" + configFile.getName() + "' -r demorealm --uusername testuser --cclientid realm-management --rolename realm-admin");
|
||||
|
||||
|
|
Loading…
Reference in a new issue