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:
|
For example:
|
||||||
[options="nowrap"]
|
[options="nowrap"]
|
||||||
----
|
----
|
||||||
$ kcadm.sh get users -r demorealm -q email=google.com
|
$ kcadm.sh get users -r demorealm -q q=email:google.com
|
||||||
$ kcadm.sh get users -r demorealm -q username=testuser
|
$ kcadm.sh get users -r demorealm -q q=username:testuser
|
||||||
----
|
----
|
||||||
[NOTE]
|
[NOTE]
|
||||||
====
|
====
|
||||||
Filtering does not use exact matching. This example matches the value of the `username` attribute against the `\*testuser*` pattern.
|
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]
|
[discrete]
|
||||||
==== Getting a specific user
|
==== Getting a specific user
|
||||||
|
|
|
@ -113,7 +113,7 @@ public abstract class AbstractRequestCmd extends AbstractAuthOptionsCmd {
|
||||||
@ArgGroup(exclusive = true, multiplicity = "0..*")
|
@ArgGroup(exclusive = true, multiplicity = "0..*")
|
||||||
List<AttributeOperations> rawAttributeOperations = new ArrayList<>();
|
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<>();
|
List<String> rawFilters = new LinkedList<>();
|
||||||
|
|
||||||
@Parameters(arity = "0..1")
|
@Parameters(arity = "0..1")
|
||||||
|
@ -142,12 +142,7 @@ public abstract class AbstractRequestCmd extends AbstractAuthOptionsCmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String arg : rawFilters) {
|
for (String arg : rawFilters) {
|
||||||
String[] keyVal;
|
String[] keyVal = parseKeyVal(arg);
|
||||||
if (arg.indexOf("=") == -1) {
|
|
||||||
keyVal = new String[] {"", arg};
|
|
||||||
} else {
|
|
||||||
keyVal = parseKeyVal(arg);
|
|
||||||
}
|
|
||||||
filter.put(keyVal[0], keyVal[1]);
|
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(" -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(" -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(" -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(" -h, --header NAME=VALUE Set request header NAME to VALUE");
|
||||||
out.println();
|
out.println();
|
||||||
out.println(" -H, --print-headers Print response headers");
|
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(" -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(" -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(" -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(" -h, --header NAME=VALUE Set request header NAME to VALUE");
|
||||||
out.println();
|
out.println();
|
||||||
out.println(" -H, --print-headers Print response headers");
|
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(" 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(" 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(" -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(" -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(" -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' ");
|
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("Note: 'users' endpoint knows how to handle --offset and --limit. Most other endpoints don't.");
|
||||||
out.println();
|
out.println();
|
||||||
out.println("Get all users whose 'username' matches '*test*' pattern, and 'email' matches '*@google.com*':");
|
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();
|
||||||
out.println("Note: it is the 'users' endpoint that interprets query parameters 'username', and 'email' in such a way that");
|
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.");
|
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(" -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(" -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(" -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(" -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(" -m, --merge Merge new values with existing configuration on the server");
|
||||||
out.println(" Merge is automatically enabled unless --file is specified");
|
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"));
|
query.append(params.getKey()).append("=").append(URLEncoder.encode(params.getValue(), "utf-8"));
|
||||||
} catch (Exception e) {
|
} 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;
|
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.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.client.cli.config.FileConfigHandler;
|
import org.keycloak.client.cli.config.FileConfigHandler;
|
||||||
|
@ -13,9 +11,14 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.StreamSupport;
|
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.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.admin.AbstractAdminTest.loadJson;
|
||||||
import static org.keycloak.testsuite.cli.KcAdmExec.execute;
|
import static org.keycloak.testsuite.cli.KcAdmExec.execute;
|
||||||
|
|
||||||
|
@ -48,6 +51,16 @@ public class KcAdmSessionTest extends AbstractAdmCliTest {
|
||||||
assertExitCodeAndStreamSizes(exe, 0, 1, 0);
|
assertExitCodeAndStreamSizes(exe, 0, 1, 0);
|
||||||
String userId = exe.stdoutLines().get(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
|
// add realm admin capabilities to user
|
||||||
exe = execute("add-roles --config '" + configFile.getName() + "' -r demorealm --uusername testuser --cclientid realm-management --rolename realm-admin");
|
exe = execute("add-roles --config '" + configFile.getName() + "' -r demorealm --uusername testuser --cclientid realm-management --rolename realm-admin");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue