Query
Examples in this documentation depend on features activated in the The code samples demonstrate how to contact the server over HTTPS using the deployment CA certificate. Before trying the samples, generate the CA certificate in PEM format from the server deployment ID and password:
|
To search, use HTTP GET with at least a _queryFilter=<filter-expression>
parameter
and other applicable parameters as necessary, such as scope
.
For reference details, refer to:
Example query filters
The following table shows LDAP search filters and corresponding query filter expressions:
LDAP Filter | REST Filter |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
For details on which index to configure for a specific filter, refer to Necessary indexes.
Build query filters
For query operations, the <filter-expression> has the following building blocks. You must URL-encode the filter expressions. This page shows them without URL-encoding to make them easier to read.
In filter expressions, the simplest <json-pointer> is a JSON field name. A <json-pointer> can also reference nested elements. For details, read RFC 6901, JavaScript Object Notation (JSON) Pointer.
The HDAP does not support
|
- Comparison expressions
-
Build filters using the following comparison expressions:
<json-pointer> eq <json-value>
-
Matches when the pointer equals the value.
Show example
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \ --get \ --cacert ca-cert.pem \ --user dc=com/dc=example/ou=People/uid=kvaughan:bribery \ --data "_queryFilter=mail+eq+'bjensen@example.com'" \ --data '_fields=cn' \ --data '_prettyPrint=true' \ --data 'scope=sub' \ 'https://localhost:8443/hdap/dc=com/dc=example/ou=People' { "result" : [ { "_id" : "dc=com/dc=example/ou=People/uid=bjensen", "_rev" : "<revision>", "cn" : [ "Barbara Jensen", "Babs Jensen" ] } ], "resultCount" : 1, "pagedResultsCookie" : null, "totalPagedResultsPolicy" : "NONE", "totalPagedResults" : -1, "remainingPagedResults" : -1 }
(async () => { const { authenticate, doRequest, getOptions } = require('./utils') const options = getOptions({ path: "/hdap/dc=com/dc=example/ou=People?_queryFilter=mail+eq+'bjensen@example.com'&_fields=cn&scope=sub" }) const jwt = await authenticate(options) options.headers['Authorization'] = 'Bearer ' + jwt const response = await doRequest('HDAP: query eq', options) console.log(response) })().catch(error => { console.error(error) })
Source files for this sample: query-eq.js, utils.js
#!/usr/bin/env python3 import requests import utils params = { '_fields': 'cn', '_queryFilter': 'mail eq "bjensen@example.com"', 'scope': 'sub' } jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' } response = requests.get( f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People', headers=headers, params=params, verify=utils.ca_pem) print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-eq.py
require_relative 'utils.rb' require 'faraday' utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') options = { ca_file: utils.ca_pem } jwt = utils.authenticate query = { "_fields": "cn", "_queryFilter": "mail eq 'bjensen@example.com'", "scope": "sub" } hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f| f.headers['Content-Type'] = 'application/json' f.request :authorization, 'Bearer', jwt end response = hdap.get('dc=com/dc=example/ou=People') puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-eq.rb
HDAP Ruby examples require Ruby 3.2 and the
faraday
andjson
gems. -
<json-pointer> co <json-value>
-
Matches when the pointer contains the value.
Show example
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \ --get \ --cacert ca-cert.pem \ --user dc=com/dc=example/ou=People/uid=kvaughan:bribery \ --data "_queryFilter=mail+co+'jensen'" \ --data '_fields=cn' \ --data '_prettyPrint=true' \ --data 'scope=sub' \ 'https://localhost:8443/hdap/dc=com/dc=example/ou=People' { "result" : [ { "_id" : "dc=com/dc=example/ou=People/uid=ajensen", "_rev" : "<revision>", "cn" : [ "Allison Jensen" ] }, { "_id" : "dc=com/dc=example/ou=People/uid=bjensen", "_rev" : "<revision>", "cn" : [ "Barbara Jensen", "Babs Jensen" ] }, { "_id" : "dc=com/dc=example/ou=People/uid=gjensen", "_rev" : "<revision>", "cn" : [ "Gern Jensen" ] }, { "_id" : "dc=com/dc=example/ou=People/uid=jjensen", "_rev" : "<revision>", "cn" : [ "Jody Jensen" ] }, { "_id" : "dc=com/dc=example/ou=People/uid=kjensen", "_rev" : "<revision>", "cn" : [ "Kurt Jensen" ] }, { "_id" : "dc=com/dc=example/ou=People/uid=rjensen", "_rev" : "<revision>", "cn" : [ "Richard Jensen" ] }, { "_id" : "dc=com/dc=example/ou=People/uid=tjensen", "_rev" : "<revision>", "cn" : [ "Ted Jensen" ] } ], "resultCount" : 7, "pagedResultsCookie" : null, "totalPagedResultsPolicy" : "NONE", "totalPagedResults" : -1, "remainingPagedResults" : -1 }
(async () => { const { authenticate, doRequest, getOptions } = require('./utils') const options = getOptions({ path: "/hdap/dc=com/dc=example/ou=People?_queryFilter=mail+co+'jensen'&_fields=cn&scope=sub" }) const jwt = await authenticate(options) options.headers['Authorization'] = 'Bearer ' + jwt const response = await doRequest('HDAP: query co', options) console.log(response) })().catch(error => { console.error(error) })
Source files for this sample: query-co.js, utils.js
#!/usr/bin/env python3 import requests import utils params = { '_fields': 'cn', '_queryFilter': 'mail co "jensen"', 'scope': 'sub' } jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' } response = requests.get( f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People', headers=headers, params=params, verify=utils.ca_pem) print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-co.py
require_relative 'utils.rb' require 'faraday' utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') options = { ca_file: utils.ca_pem } jwt = utils.authenticate query = { "_fields": "cn", "_queryFilter": "mail co 'jensen'", "scope": "sub" } hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f| f.headers['Content-Type'] = 'application/json' f.request :authorization, 'Bearer', jwt end response = hdap.get('dc=com/dc=example/ou=People') puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-co.rb
HDAP Ruby examples require Ruby 3.2 and the
faraday
andjson
gems. -
<json-pointer> sw <json-value>
-
Matches when the pointer starts with the value.
Show example
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \ --get \ --cacert ca-cert.pem \ --user dc=com/dc=example/ou=People/uid=kvaughan:bribery \ --data "_queryFilter=mail+sw+'ab'" \ --data '_fields=cn' \ --data '_prettyPrint=true' \ --data 'scope=sub' \ 'https://localhost:8443/hdap/dc=com/dc=example/ou=People' { "result" : [ { "_id" : "dc=com/dc=example/ou=People/uid=abarnes", "_rev" : "<revision>", "cn" : [ "Anne-Louise Barnes" ] }, { "_id" : "dc=com/dc=example/ou=People/uid=abergin", "_rev" : "<revision>", "cn" : [ "Andy Bergin" ] } ], "resultCount" : 2, "pagedResultsCookie" : null, "totalPagedResultsPolicy" : "NONE", "totalPagedResults" : -1, "remainingPagedResults" : -1 }
(async () => { const { authenticate, doRequest, getOptions } = require('./utils') const options = getOptions({ path: "/hdap/dc=com/dc=example/ou=People?_queryFilter=mail+sw+'ab'&_fields=cn&scope=sub" }) const jwt = await authenticate(options) options.headers['Authorization'] = 'Bearer ' + jwt const response = await doRequest('HDAP: query sw', options) console.log(response) })().catch(error => { console.error(error) })
Source files for this sample: query-sw.js, utils.js
#!/usr/bin/env python3 import requests import utils params = { '_fields': 'cn', '_queryFilter': 'mail sw "ab"', 'scope': 'sub' } jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' } response = requests.get( f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People', headers=headers, params=params, verify=utils.ca_pem) print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-sw.py
require_relative 'utils.rb' require 'faraday' utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') options = { ca_file: utils.ca_pem } jwt = utils.authenticate query = { "_fields": "cn", "_queryFilter": "mail sw 'ab'", "scope": "sub" } hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f| f.headers['Content-Type'] = 'application/json' f.request :authorization, 'Bearer', jwt end response = hdap.get('dc=com/dc=example/ou=People') puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-eq.rb
HDAP Ruby examples require Ruby 3.2 and the
faraday
andjson
gems. -
<json-pointer> lt <json-value>
-
Matches when the pointer is less than the value.
Show example
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \ --get \ --cacert ca-cert.pem \ --user dc=com/dc=example/ou=People/uid=kvaughan:bribery \ --data "_queryFilter=mail+lt+'ac'" \ --data '_fields=cn' \ --data '_prettyPrint=true' \ --data 'scope=sub' \ 'https://localhost:8443/hdap/dc=com/dc=example/ou=People' { "result" : [ { "_id" : "dc=com/dc=example/ou=People/uid=abarnes", "_rev" : "<revision>", "cn" : [ "Anne-Louise Barnes" ] }, { "_id" : "dc=com/dc=example/ou=People/uid=abergin", "_rev" : "<revision>", "cn" : [ "Andy Bergin" ] } ], "resultCount" : 2, "pagedResultsCookie" : null, "totalPagedResultsPolicy" : "NONE", "totalPagedResults" : -1, "remainingPagedResults" : -1 }
(async () => { const { authenticate, doRequest, getOptions } = require('./utils') const options = getOptions({ path: "/hdap/dc=com/dc=example/ou=People?_queryFilter=mail+lt+'ac'&_fields=cn&scope=sub" }) const jwt = await authenticate(options) options.headers['Authorization'] = 'Bearer ' + jwt const response = await doRequest('HDAP: query lt', options) console.log(response) })().catch(error => { console.error(error) })
Source files for this sample: query-lt.js, utils.js
#!/usr/bin/env python3 import requests import utils params = { '_fields': 'cn', '_queryFilter': 'mail lt "ac"', 'scope': 'sub' } jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' } response = requests.get( f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People', headers=headers, params=params, verify=utils.ca_pem) print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-lt.py
require_relative 'utils.rb' require 'faraday' utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') options = { ca_file: utils.ca_pem } jwt = utils.authenticate query = { "_fields": "cn", "_queryFilter": "mail lt 'ac'", "scope": "sub" } hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f| f.headers['Content-Type'] = 'application/json' f.request :authorization, 'Bearer', jwt end response = hdap.get('dc=com/dc=example/ou=People') puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-lt.rb
HDAP Ruby examples require Ruby 3.2 and the
faraday
andjson
gems. -
<json-pointer> le <json-value>
-
Matches when the pointer is less than or equal to the value.
Show example
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \ --get \ --cacert ca-cert.pem \ --user dc=com/dc=example/ou=People/uid=kvaughan:bribery \ --data "_queryFilter=mail+le+'ad'" \ --data '_fields=cn' \ --data '_prettyPrint=true' \ --data 'scope=sub' \ 'https://localhost:8443/hdap/dc=com/dc=example/ou=People' { "result" : [ { "_id" : "dc=com/dc=example/ou=People/uid=abarnes", "_rev" : "<revision>", "cn" : [ "Anne-Louise Barnes" ] }, { "_id" : "dc=com/dc=example/ou=People/uid=abergin", "_rev" : "<revision>", "cn" : [ "Andy Bergin" ] }, { "_id" : "dc=com/dc=example/ou=People/uid=achassin", "_rev" : "<revision>", "cn" : [ "Ashley Chassin" ] } ], "resultCount" : 3, "pagedResultsCookie" : null, "totalPagedResultsPolicy" : "NONE", "totalPagedResults" : -1, "remainingPagedResults" : -1 }
(async () => { const { authenticate, doRequest, getOptions } = require('./utils') const options = getOptions({ path: "/hdap/dc=com/dc=example/ou=People?_queryFilter=mail+le+'ad'&_fields=cn&scope=sub" }) const jwt = await authenticate(options) options.headers['Authorization'] = 'Bearer ' + jwt const response = await doRequest('HDAP: query le', options) console.log(response) })().catch(error => { console.error(error) })
Source files for this sample: query-le.js, utils.js
#!/usr/bin/env python3 import requests import utils params = { '_fields': 'cn', '_queryFilter': 'mail le "ad"', 'scope': 'sub' } jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' } response = requests.get( f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People', headers=headers, params=params, verify=utils.ca_pem) print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-le.py
require_relative 'utils.rb' require 'faraday' utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') options = { ca_file: utils.ca_pem } jwt = utils.authenticate query = { "_fields": "cn", "_queryFilter": "mail le 'ad'", "scope": "sub" } hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f| f.headers['Content-Type'] = 'application/json' f.request :authorization, 'Bearer', jwt end response = hdap.get('dc=com/dc=example/ou=People') puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-le.rb
HDAP Ruby examples require Ruby 3.2 and the
faraday
andjson
gems. -
<json-pointer> gt <json-value>
-
Matches when the pointer is greater than the value.
Show example
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \ --get \ --cacert ca-cert.pem \ --user dc=com/dc=example/ou=People/uid=kvaughan:bribery \ --data "_queryFilter=mail+gt+'wa'" \ --data '_fields=cn' \ --data '_prettyPrint=true' \ --data 'scope=sub' \ 'https://localhost:8443/hdap/dc=com/dc=example/ou=People' { "result" : [ { "_id" : "dc=com/dc=example/ou=People/uid=wlutz", "_rev" : "<revision>", "cn" : [ "Wendy Lutz" ] } ], "resultCount" : 1, "pagedResultsCookie" : null, "totalPagedResultsPolicy" : "NONE", "totalPagedResults" : -1, "remainingPagedResults" : -1 }
(async () => { const { authenticate, doRequest, getOptions } = require('./utils') const options = getOptions({ path: "/hdap/dc=com/dc=example/ou=People?_queryFilter=mail+gt+'wa'&_fields=cn&scope=sub" }) const jwt = await authenticate(options) options.headers['Authorization'] = 'Bearer ' + jwt const response = await doRequest('HDAP: query gt', options) console.log(response) })().catch(error => { console.error(error) })
Source files for this sample: query-gt.js, utils.js
#!/usr/bin/env python3 import requests import utils params = { '_fields': 'cn', '_queryFilter': 'mail gt "wa"', 'scope': 'sub' } jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' } response = requests.get( f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People', headers=headers, params=params, verify=utils.ca_pem) print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-gt.py
require_relative 'utils.rb' require 'faraday' utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') options = { ca_file: utils.ca_pem } jwt = utils.authenticate query = { "_fields": "cn", "_queryFilter": "mail gt 'wa'", "scope": "sub" } hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f| f.headers['Content-Type'] = 'application/json' f.request :authorization, 'Bearer', jwt end response = hdap.get('dc=com/dc=example/ou=People') puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-gt.rb
HDAP Ruby examples require Ruby 3.2 and the
faraday
andjson
gems. -
<json-pointer> ge <json-value>
-
Matches when the pointer is greater than or equal to the value.
Show example
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \ --get \ --cacert ca-cert.pem \ --user dc=com/dc=example/ou=People/uid=kvaughan:bribery \ --data "_queryFilter=mail+ge+'va'" \ --data '_fields=cn' \ --data '_prettyPrint=true' \ --data 'scope=sub' \ 'https://localhost:8443/hdap/dc=com/dc=example/ou=People' { "result" : [ { "_id" : "dc=com/dc=example/ou=People/uid=wlutz", "_rev" : "<revision>", "cn" : [ "Wendy Lutz" ] } ], "resultCount" : 1, "pagedResultsCookie" : null, "totalPagedResultsPolicy" : "NONE", "totalPagedResults" : -1, "remainingPagedResults" : -1 }
(async () => { const { authenticate, doRequest, getOptions } = require('./utils') const options = getOptions({ path: "/hdap/dc=com/dc=example/ou=People?_queryFilter=mail+ge+'va'&_fields=cn&scope=sub" }) const jwt = await authenticate(options) options.headers['Authorization'] = 'Bearer ' + jwt const response = await doRequest('HDAP: query ge', options) console.log(response) })().catch(error => { console.error(error) })
Source files for this sample: query-ge.js, utils.js
#!/usr/bin/env python3 import requests import utils params = { '_fields': 'cn', '_queryFilter': 'mail ge "va"', 'scope': 'sub' } jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' } response = requests.get( f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People', headers=headers, params=params, verify=utils.ca_pem) print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-ge.py
require_relative 'utils.rb' require 'faraday' utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') options = { ca_file: utils.ca_pem } jwt = utils.authenticate query = { "_fields": "cn", "_queryFilter": "mail ge 'va'", "scope": "sub" } hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f| f.headers['Content-Type'] = 'application/json' f.request :authorization, 'Bearer', jwt end response = hdap.get('dc=com/dc=example/ou=People') puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-ge.rb
HDAP Ruby examples require Ruby 3.2 and the
faraday
andjson
gems. -
- Presence expression
-
<json-pointer> pr
matches a resource where the pointer is present.Show example
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \ --get \ --cacert ca-cert.pem \ --user dc=com/dc=example/ou=People/uid=kvaughan:bribery \ --data "_queryFilter=cn+pr" \ --data '_fields=cn' \ --data '_prettyPrint=true' \ --data 'scope=sub' \ 'https://localhost:8443/hdap/dc=com/dc=example/ou=Groups' { "result" : [ { "_id" : "dc=com/dc=example/ou=groups/cn=Accounting%20Managers", "_rev" : "<revision>", "cn" : [ "Accounting Managers" ] }, { "_id" : "dc=com/dc=example/ou=Groups/cn=Directory%20Administrators", "_rev" : "<revision>", "cn" : [ "Directory Administrators" ] }, { "_id" : "dc=com/dc=example/ou=groups/cn=HR%20Managers", "_rev" : "<revision>", "cn" : [ "HR Managers" ] }, { "_id" : "dc=com/dc=example/ou=groups/cn=PD%20Managers", "_rev" : "<revision>", "cn" : [ "PD Managers" ] }, { "_id" : "dc=com/dc=example/ou=groups/cn=QA%20Managers", "_rev" : "<revision>", "cn" : [ "QA Managers" ] }, { "_id" : "dc=com/dc=example/ou=Groups/ou=Self%20Service/cn=Carpoolers", "_rev" : "<revision>", "cn" : [ "Carpoolers" ] } ], "resultCount" : 6, "pagedResultsCookie" : null, "totalPagedResultsPolicy" : "NONE", "totalPagedResults" : -1, "remainingPagedResults" : -1 }
(async () => { const { authenticate, doRequest, getOptions } = require('./utils') const options = getOptions({ path: '/hdap/dc=com/dc=example/ou=Groups?_queryFilter=cn+pr&_fields=cn&scope=sub' }) const jwt = await authenticate(options) options.headers['Authorization'] = 'Bearer ' + jwt const response = await doRequest('HDAP: query pr', options) console.log(response) })().catch(error => { console.error(error) })
Source files for this sample: query-pr.js, utils.js
#!/usr/bin/env python3 import requests import utils params = { '_fields': 'cn', '_queryFilter': 'cn pr', 'scope': 'sub' } jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' } response = requests.get( f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=Groups', headers=headers, params=params, verify=utils.ca_pem) print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-pr.py
require_relative 'utils.rb' require 'faraday' utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') options = { ca_file: utils.ca_pem } jwt = utils.authenticate query = { "_fields": "cn", "_queryFilter": "cn pr", "scope": "sub" } hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f| f.headers['Content-Type'] = 'application/json' f.request :authorization, 'Bearer', jwt end response = hdap.get('dc=com/dc=example/ou=Groups') puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-pr.rb
HDAP Ruby examples require Ruby 3.2 and the
faraday
andjson
gems. -
- Literal expressions
-
true
matches any resource in scope.false
matches no resources.Show example
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \ --get \ --cacert ca-cert.pem \ --user dc=com/dc=example/ou=People/uid=kvaughan:bribery \ --data "_queryFilter=true" \ --data '_fields=_id' \ --data '_prettyPrint=true' \ 'https://localhost:8443/hdap/dc=com/dc=example/ou=Groups' { "result" : [ { "_id" : "dc=com/dc=example/ou=groups/cn=Accounting%20Managers", "_rev" : "<revision>" }, { "_id" : "dc=com/dc=example/ou=Groups/cn=Directory%20Administrators", "_rev" : "<revision>" }, { "_id" : "dc=com/dc=example/ou=groups/cn=HR%20Managers", "_rev" : "<revision>" }, { "_id" : "dc=com/dc=example/ou=groups/cn=PD%20Managers", "_rev" : "<revision>" }, { "_id" : "dc=com/dc=example/ou=groups/cn=QA%20Managers", "_rev" : "<revision>" }, { "_id" : "dc=com/dc=example/ou=Groups/ou=Self%20Service", "_rev" : "<revision>" } ], "resultCount" : 6, "pagedResultsCookie" : null, "totalPagedResultsPolicy" : "NONE", "totalPagedResults" : -1, "remainingPagedResults" : -1 }
(async () => { const { authenticate, doRequest, getOptions } = require('./utils') const options = getOptions({ path: '/hdap/dc=com/dc=example/ou=Groups?_queryFilter=true&_fields=cn&scope=sub' }) const jwt = await authenticate(options) options.headers['Authorization'] = 'Bearer ' + jwt const response = await doRequest('HDAP: query true', options) console.log(response) })().catch(error => { console.error(error) })
Source files for this sample: query-true.js, utils.js
#!/usr/bin/env python3 import requests import utils params = { '_fields': 'cn', '_queryFilter': True, 'scope': 'sub' } jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' } response = requests.get( f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=Groups', headers=headers, params=params, verify=utils.ca_pem) print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-true.py
require_relative 'utils.rb' require 'faraday' utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') options = { ca_file: utils.ca_pem } jwt = utils.authenticate query = { "_fields": "cn", "_queryFilter": true, "scope": "sub" } hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f| f.headers['Content-Type'] = 'application/json' f.request :authorization, 'Bearer', jwt end response = hdap.get('dc=com/dc=example/ou=Groups') puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-true.rb
HDAP Ruby examples require Ruby 3.2 and the
faraday
andjson
gems. -
- Complex expressions
-
Combine expressions using boolean operators
and
,or
, and!
(not), and by using parentheses(<filter-expression>)
with group expressions.Show example
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \ --get \ --cacert ca-cert.pem \ --user dc=com/dc=example/ou=People/uid=kvaughan:bribery \ --data "_queryFilter=mail+co+'jensen'+and+givenName+sw+'Al'" \ --data '_fields=cn' \ --data '_prettyPrint=true' \ --data 'scope=sub' \ 'https://localhost:8443/hdap/dc=com/dc=example/ou=People' { "result" : [ { "_id" : "dc=com/dc=example/ou=People/uid=ajensen", "_rev" : "<revision>", "cn" : [ "Allison Jensen" ] } ], "resultCount" : 1, "pagedResultsCookie" : null, "totalPagedResultsPolicy" : "NONE", "totalPagedResults" : -1, "remainingPagedResults" : -1 }
(async () => { const { authenticate, doRequest, getOptions } = require('./utils') const filter = encodeURIComponent("mail co 'jensen' and givenName sw 'Al'") const options = getOptions({ path: `/hdap/dc=com/dc=example/ou=People?_queryFilter=${filter}&_fields=cn&scope=sub` }) const jwt = await authenticate(options) options.headers['Authorization'] = 'Bearer ' + jwt const response = await doRequest('HDAP: complex query', options) console.log(response) })().catch(error => { console.error(error) })
Source files for this sample: query-complex.js, utils.js
#!/usr/bin/env python3 import requests import utils params = { '_fields': 'cn', '_queryFilter': 'mail co "jensen" and givenName sw "Al"', 'scope': 'sub' } jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' } response = requests.get( f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People', headers=headers, params=params, verify=utils.ca_pem) print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-complex.py
require_relative 'utils.rb' require 'faraday' utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery') options = { ca_file: utils.ca_pem } jwt = utils.authenticate query = { "_fields": "cn", "_queryFilter": "mail co 'jensen' and givenName sw 'Al'", "scope": "sub" } hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f| f.headers['Content-Type'] = 'application/json' f.request :authorization, 'Bearer', jwt end response = hdap.get('dc=com/dc=example/ou=People') puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-complex.rb
HDAP Ruby examples require Ruby 3.2 and the
faraday
andjson
gems. -
Graph-like queries
Collective attributes provide a mechanism to inherit LDAP attributes from other entries. HDAP relies on this mechanism for graph-like queries.
The ds-evaluation
setup profile uses collective attributes to inherit LDAP attribute values
for street address from location and quota settings from class of service.
Show example
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \
--get \
--cacert ca-cert.pem \
--user dc=com/dc=example/ou=People/uid=kvaughan:bribery \
--data "_queryFilter=(mail+co+'jensen'+and+l+eq+'San+Francisco'+and+classOfService+eq+'bronze')" \
--data '_fields=diskQuota,mailQuota,street' \
--data '_prettyPrint=true' \
--data 'scope=sub' \
'https://localhost:8443/hdap/dc=com/dc=example/ou=People'
{
"result" : [ {
"_id" : "dc=com/dc=example/ou=People/uid=bjensen",
"_rev" : "<revision>",
"street" : [ "201 Mission Street Suite 2900" ],
"mailQuota" : [ "1 GB" ],
"diskQuota" : [ "10 GB" ]
} ],
"resultCount" : 1,
"pagedResultsCookie" : null,
"totalPagedResultsPolicy" : "NONE",
"totalPagedResults" : -1,
"remainingPagedResults" : -1
}
(async () => {
const { authenticate, doRequest, getOptions } = require('./utils')
const filter = "mail+co+'jensen'+and+l+eq+'San+Francisco'+and+classOfService+eq+'bronze'"
const options = getOptions({
path: `/hdap/dc=com/dc=example/ou=People?_queryFilter=${filter}&_fields=diskQuota,mailQuota,street&scope=sub`
})
const jwt = await authenticate(options)
options.headers['Authorization'] = 'Bearer ' + jwt
const response = await doRequest('HDAP: graph query', options)
console.log(response)
})().catch(error => { console.error(error) })
Source files for this sample: query-graph.js, utils.js
#!/usr/bin/env python3
import requests
import utils
params = {
'_fields': 'diskQuota,mailQuota,street',
'_queryFilter': 'mail co "jensen" and l eq "San Francisco" and classOfService eq "bronze"',
'scope': 'sub'
}
jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' }
response = requests.get(
f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People',
headers=headers,
params=params,
verify=utils.ca_pem)
print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-graph.py
require_relative 'utils.rb'
require 'faraday'
utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
options = { ca_file: utils.ca_pem }
jwt = utils.authenticate
query = {
"_fields": "diskQuota,mailQuota,street",
"_queryFilter": "mail co 'jensen' and l eq 'San Francisco' and classOfService eq 'bronze'",
"scope": "sub"
}
hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f|
f.headers['Content-Type'] = 'application/json'
f.request :authorization, 'Bearer', jwt
end
response = hdap.get('dc=com/dc=example/ou=People')
puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-graph.rb
HDAP Ruby examples require Ruby 3.2 and the faraday
and json
gems.
Configure collective attributes as necessary for your graph-like queries.
Queries and JSON attributes
The default JSON query index works for JSON attributes that hold arbitrary JSON objects.
This includes JSON with nested objects, such as {"array":[{"x":1,"y":2},{"x":3,"y":4}]}
.
As a result, HDAP filter expressions can target JSON fields in indexed JSON attribute objects.
HDAP query filter expressions support the
grouping operators described in RFC 7644, section 3.4.2.2. Filtering, Table 5: Grouping Operators.
In other words, HDAP query filter expressions can use complex attribute filter grouping,
with brackets ([]
) to group expressions in the filter.
Complex attribute filter grouping lets filter expressions target array objects.
This search finds an entry with a json
attribute containing an array
of objects:
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \
--get \
--cacert ca-cert.pem \
--user dc=com/dc=example/ou=People/uid=kvaughan:bribery \
--data-urlencode "_queryFilter=(json/array[x eq 1] and json/array[y eq 4])" \
--data '_fields=json' \
--data '_prettyPrint=true' \
--data 'scope=sub' \
'https://localhost:8443/hdap/dc=com/dc=example/ou=People'
{
"result" : [ {
"_id" : "dc=com/dc=example/ou=People/uid=abarnes",
"_rev" : "<revision>",
"json" : [ {
"array" : [ {
"x" : 1,
"y" : 2
}, {
"x" : 3,
"y" : 4
} ]
} ]
} ],
"resultCount" : 1,
"pagedResultsCookie" : null,
"totalPagedResultsPolicy" : "NONE",
"totalPagedResults" : -1,
"remainingPagedResults" : -1
}
(async () => {
const { authenticate, doRequest, getOptions } = require('./utils')
const filter = encodeURIComponent('(json/array[x eq 1] and json/array[y eq 4])')
const options = getOptions({
path: `/hdap/dc=com/dc=example/ou=People?_queryFilter=${filter}&_fields=json&scope=sub`
})
const jwt = await authenticate(options)
options.headers['Authorization'] = 'Bearer ' + jwt
const response = await doRequest('HDAP: JSON query', options)
console.log(response)
})().catch(error => { console.error(error) })
Source files for this sample: query-json.js, utils.js
#!/usr/bin/env python3
import requests
import utils
params = {
'_fields': 'json',
'_queryFilter': '(json/array[x eq 1] and json/array[y eq 4])',
'scope': 'sub'
}
jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' }
response = requests.get(
f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People',
headers=headers,
params=params,
verify=utils.ca_pem)
print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-json.py
require_relative 'utils.rb'
require 'faraday'
utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
options = { ca_file: utils.ca_pem }
jwt = utils.authenticate
query = {
"_fields": "json",
"_queryFilter": "(json/array[x eq 1] and json/array[y eq 4])",
"scope": "sub"
}
hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f|
f.headers['Content-Type'] = 'application/json'
f.request :authorization, 'Bearer', jwt
end
response = hdap.get('dc=com/dc=example/ou=People')
puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-json.rb
HDAP Ruby examples require Ruby 3.2 and the faraday
and json
gems.
-
The filter
json/array[x eq 1] and json/array[y eq 4]
matches because it matches both objects in the array. -
The filter
json/array[x eq 1 and y eq 2]
matches because it matches the first object of the array. -
The filter
json/array[x eq 1 and y eq 4]
fails to match, because the array has no object{"x":1,"y":4}
.
Count child resources
Use the _countOnly=true
query string parameter to get the number of child resources directly beneath a resource.
You must also set _queryFilter=true
and leave scope=one
(default):
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \
--get \
--user dc=com/dc=example/ou=People/uid=kvaughan:bribery \
--cacert ca-cert.pem \
--header 'Accept-API-Version: protocol=2.2,resource=1.0' \
--data '_countOnly=true' \
--data '_queryFilter=true' \
--data '_prettyPrint=true' \
'https://localhost:8443/hdap/dc=com/dc=example/ou=People'
{
"result" : [ ],
"resultCount" : 100153,
"pagedResultsCookie" : null,
"totalPagedResultsPolicy" : "ESTIMATE",
"totalPagedResults" : 100153,
"remainingPagedResults" : -1
}
(async () => {
const { authenticate, doRequest, getOptions } = require('./utils')
const options = getOptions({
path: '/hdap/dc=com/dc=example/ou=People?_queryFilter=true&_countOnly=true',
})
const jwt = await authenticate(options)
options.headers['Accept-API-Version'] = 'protocol=2.2,resource=1.0'
options.headers['Authorization'] = 'Bearer ' + jwt
const response = await doRequest('HDAP: query for count', options)
console.log(response)
})().catch(error => { console.error(error) })
Source files for this sample: query-count.js, utils.js
#!/usr/bin/env python3
import requests
import utils
params = {
'_countOnly': True,
'_queryFilter': True
}
jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {jwt}',
'Accept-API-Version': 'protocol=2.2,resource=1.0'
}
response = requests.get(
f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People',
headers=headers,
params=params,
verify=utils.ca_pem)
print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-count.py
require_relative 'utils.rb'
require 'faraday'
utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
options = { ca_file: utils.ca_pem }
jwt = utils.authenticate
query = {
"_countOnly": true,
"_queryFilter": true
}
hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f|
f.headers['Content-Type'] = 'application/json'
f.headers['Accept-API-Version'] = 'protocol=2.2,resource=1.0'
f.request :authorization, 'Bearer', jwt
end
response = hdap.get('dc=com/dc=example/ou=People')
puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-count.rb
HDAP Ruby examples require Ruby 3.2 and the faraday
and json
gems.
Notice the search returns an empty result
array.
This feature relies on the
numSubordinates
virtual attribute.
Paged results
Get results one page at a time with these query string parameters:
-
_pageSize=<number>
-
_pagedResultsCookie=<cookie>
Show request for first page of five results
-
Curl
-
JavaScript
-
Python
-
Ruby
# Request five results per page and retrieve the first page:
$ curl \
--get \
--cacert ca-cert.pem \
--user dc=com/dc=example/ou=People/uid=kvaughan:bribery \
--data "_queryFilter=objectClass+eq+'posixAccount'" \
--data '_pageSize=5' \
--data '_fields=_id' \
--data '_prettyPrint=true' \
--data 'scope=sub' \
'https://localhost:8443/hdap/dc=com/dc=example/ou=People'
{
"result" : [ {
"_id" : "dc=com/dc=example/ou=People/uid=abarnes",
"_rev" : "<revision>"
}, {
"_id" : "dc=com/dc=example/ou=People/uid=abergin",
"_rev" : "<revision>"
}, {
"_id" : "dc=com/dc=example/ou=People/uid=achassin",
"_rev" : "<revision>"
}, {
"_id" : "dc=com/dc=example/ou=People/uid=ahall",
"_rev" : "<revision>"
}, {
"_id" : "dc=com/dc=example/ou=People/uid=ahel",
"_rev" : "<revision>"
} ],
"resultCount" : 5,
"pagedResultsCookie" : "AAAAAAAAABE=",
"totalPagedResultsPolicy" : "NONE",
"totalPagedResults" : -1,
"remainingPagedResults" : -1
}
(async () => {
const { authenticate, doRequest, getOptions } = require('./utils')
const filter = "objectClass+eq+'posixAccount'"
const options = getOptions({
path: `/hdap/dc=com/dc=example/ou=People?_queryFilter=${filter}&_pageSize=5&_fields=_id&scope=sub`
})
const jwt = await authenticate(options)
options.headers['Authorization'] = 'Bearer ' + jwt
const response = await doRequest('HDAP: query first five paged results', options)
console.log(response)
})().catch(error => { console.error(error) })
Source files for this sample: query-paged-first-five.js, utils.js
#!/usr/bin/env python3
import requests
import utils
params = {
'_fields': '_id',
'_queryFilter': 'objectClass eq "posixAccount"',
'_pageSize': 5,
'scope': 'sub'
}
jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' }
response = requests.get(
f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People',
headers=headers,
params=params,
verify=utils.ca_pem)
print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-paged-first-five.py
require_relative 'utils.rb'
require 'faraday'
utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
options = { ca_file: utils.ca_pem }
jwt = utils.authenticate
query = {
"_fields": "_id",
"_queryFilter": "objectClass eq 'posixAccount'",
"_pageSize": 5,
"scope": "sub"
}
hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f|
f.headers['Content-Type'] = 'application/json'
f.request :authorization, 'Bearer', jwt
end
response = hdap.get('dc=com/dc=example/ou=People')
puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-paged-first-five.rb
HDAP Ruby examples require Ruby 3.2 and the faraday
and json
gems.
Show request for next page of five results
-
Curl
-
JavaScript
-
Python
-
Ruby
# Provide the cookie to request the next five results:
$ export COOKIE=$(cut -d \" -f 4 <(grep pagedResultsCookie \
<(curl \
--get \
--cacert ca-cert.pem \
--user dc=com/dc=example/ou=People/uid=kvaughan:bribery \
--data "_queryFilter=objectClass+eq+'posixAccount'" \
--data '_pageSize=5' \
--data '_fields=_id' \
--data '_prettyPrint=true' \
--data 'scope=sub' \
'https://localhost:8443/hdap/dc=com/dc=example/ou=People')))
$ curl \
--get \
--cacert ca-cert.pem \
--user dc=com/dc=example/ou=People/uid=kvaughan:bribery \
--data "_queryFilter=objectClass+eq+'posixAccount'" \
--data '_pageSize=5' \
--data "_pagedResultsCookie=$COOKIE" \
--data '_fields=_id' \
--data '_prettyPrint=true' \
--data 'scope=sub' \
'https://localhost:8443/hdap/dc=com/dc=example/ou=People'
{
"result" : [ {
"_id" : "dc=com/dc=example/ou=People/uid=ahunter",
"_rev" : "<revision>"
}, {
"_id" : "dc=com/dc=example/ou=People/uid=ajensen",
"_rev" : "<revision>"
}, {
"_id" : "dc=com/dc=example/ou=People/uid=aknutson",
"_rev" : "<revision>"
}, {
"_id" : "dc=com/dc=example/ou=People/uid=alangdon",
"_rev" : "<revision>"
}, {
"_id" : "dc=com/dc=example/ou=People/uid=alutz",
"_rev" : "<revision>"
} ],
"resultCount" : 5,
"pagedResultsCookie" : "AAAAAAAAABE=",
"totalPagedResultsPolicy" : "NONE",
"totalPagedResults" : -1,
"remainingPagedResults" : -1
}
(async () => {
const { authenticate, doRequest, getOptions } = require('./utils')
const filter = "objectClass+eq+'posixAccount'"
const options = getOptions({
path: `/hdap/dc=com/dc=example/ou=People?_queryFilter=${filter}&_pageSize=5&_fields=_id&scope=sub`
})
const jwt = await authenticate(options)
options.headers['Authorization'] = 'Bearer ' + jwt
let response = await doRequest('HDAP: query first five paged results', options)
console.log(response)
const cookie = JSON.parse(response.data).pagedResultsCookie
options.path += `&_pagedResultsCookie=${cookie}`
response = await doRequest('HDAP: query next five paged results', options)
console.log(response)
})().catch(error => { console.error(error) })
Source files for this sample: query-paged-next-five.js, utils.js
#!/usr/bin/env python3
import requests
import utils
resource = f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People'
params = {
'_fields': '_id',
'_queryFilter': 'objectClass eq "posixAccount"',
'_pageSize': 5,
'scope': 'sub'
}
jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' }
response = requests.get(
resource,
headers=headers,
params=params,
verify=utils.ca_pem)
cookie = response.json()['pagedResultsCookie']
params['_pagedResultsCookie'] = cookie
response = requests.get(
resource,
headers=headers,
params=params,
verify=utils.ca_pem)
print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-paged-next-five.py
require_relative 'utils.rb'
require 'faraday'
utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
options = { ca_file: utils.ca_pem }
jwt = utils.authenticate
query = {
"_fields": "_id",
"_queryFilter": "objectClass eq 'posixAccount'",
"_pageSize": 5,
"scope": "sub"
}
resource = 'dc=com/dc=example/ou=People'
hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f|
f.headers['Content-Type'] = 'application/json'
f.request :authorization, 'Bearer', jwt
end
cookie = JSON.parse(hdap.get(resource).body, symbolize_names: true)[:pagedResultsCookie]
query['_pagedResultsCookie'] = cookie
hdap.params = query
response = hdap.get(resource)
puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-paged-next-five.rb
HDAP Ruby examples require Ruby 3.2 and the faraday
and json
gems.
Notice the following features of the responses:
-
"totalPagedResultsPolicy" : "NONE"
means HDAP did not calculate the counts. -
"remainingPagedResults" : -1
means HDAP did not count the remaining results.HDAP never counts
remainingPagedResults
because it would require a potentially costly calculation to determine the current position in the total result set. -
"totalPagedResults" : -1
means HDAP did not count the total results.
When the query has the following characteristics, the response contains an estimated totalPagedResults
count:
-
The request specifies the policy using the parameter
_totalPagedResultsPolicy=ESTIMATE
. -
The
_pageSize
parameter is an integer greater than zero. -
The LDAP search for the query is indexed.
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \
--get \
--cacert ca-cert.pem \
--user dc=com/dc=example/ou=People/uid=kvaughan:bribery \
--data "_queryFilter=mail+co+'jensen'" \
--data '_pageSize=2' \
--data '_totalPagedResultsPolicy=ESTIMATE' \
--data '_fields=_id' \
--data '_prettyPrint=true' \
--data 'scope=sub' \
'https://localhost:8443/hdap/dc=com/dc=example/ou=People'
{
"result" : [ {
"_id" : "dc=com/dc=example/ou=People/uid=ajensen",
"_rev" : "<revision>"
}, {
"_id" : "dc=com/dc=example/ou=People/uid=bjensen",
"_rev" : "<revision>"
} ],
"resultCount" : 2,
"pagedResultsCookie" : "AAAAAAAAAEI=",
"totalPagedResultsPolicy" : "ESTIMATE",
"totalPagedResults" : 7,
"remainingPagedResults" : -1
}
(async () => {
const { authenticate, doRequest, getOptions } = require('./utils')
const filter = "mail+co+'jensen'"
const pageParams = '_pageSize=2&_totalPagedResultsPolicy=ESTIMATE'
const options = getOptions({
path: `/hdap/dc=com/dc=example/ou=People?_queryFilter=${filter}&${pageParams}&_fields=_id&scope=sub`
})
const jwt = await authenticate(options)
options.headers['Authorization'] = 'Bearer ' + jwt
const response = await doRequest('HDAP: paged query', options)
console.log(response)
})().catch(error => { console.error(error) })
Source files for this sample: query-paged.js, utils.js
#!/usr/bin/env python3
import requests
import utils
params = {
'_fields': '_id',
'_queryFilter': 'mail co "jensen"',
'_pageSize': 2,
'_totalPagedResultsPolicy': 'ESTIMATE',
'scope': 'sub'
}
jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' }
response = requests.get(
f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People',
headers=headers,
params=params,
verify=utils.ca_pem)
print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-paged.py
require_relative 'utils.rb'
require 'faraday'
utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
options = { ca_file: utils.ca_pem }
jwt = utils.authenticate
query = {
"_fields": "_id",
"_queryFilter": "mail co 'jensen'",
"_pageSize": 2,
"_totalPagedResultsPolicy": "ESTIMATE",
"scope": "sub"
}
hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f|
f.headers['Content-Type'] = 'application/json'
f.request :authorization, 'Bearer', jwt
end
response = hdap.get('dc=com/dc=example/ou=People')
puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-paged.rb
HDAP Ruby examples require Ruby 3.2 and the faraday
and json
gems.
The estimated number of results can be useful, for example, when the LDAP search uses a big index or a VLV index and the total number of results is large.
Server-side sort
Use the _sortKeys
parameter
to have HDAP sort the query results based on one or more fields in the resources.
The following example sorts results in reverse order by given name (-givenName
):
-
Curl
-
JavaScript
-
Python
-
Ruby
$ curl \
--get \
--cacert ca-cert.pem \
--user dc=com/dc=example/ou=People/uid=kvaughan:bribery \
--data "_queryFilter=sn+co+'barnes'" \
--data '_sortKeys=-givenName' \
--data '_fields=cn' \
--data '_prettyPrint=true' \
--data 'scope=sub' \
'https://localhost:8443/hdap/dc=com/dc=example/ou=People'
(async () => {
const { authenticate, doRequest, getOptions } = require('./utils')
const filter = "sn+co+'barnes'"
const options = getOptions({
path: `/hdap/dc=com/dc=example/ou=People?_queryFilter=${filter}&_sortKeys=-givenName&_fields=cn&scope=sub`
})
const jwt = await authenticate(options)
options.headers['Authorization'] = 'Bearer ' + jwt
const response = await doRequest('HDAP: query with server-side sort', options)
console.log(response)
})().catch(error => { console.error(error) })
Source files for this sample: query-sss.js, utils.js
#!/usr/bin/env python3
import requests
import utils
params = {
'_fields': 'cn',
'_queryFilter': 'sn co "barnes"',
'_sortKeys': '-givenName',
'scope': 'sub'
}
jwt = utils.authenticate('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {jwt}' }
response = requests.get(
f'https://{utils.host}:{utils.port}/hdap/dc=com/dc=example/ou=People',
headers=headers,
params=params,
verify=utils.ca_pem)
print('Status code: %d\nJSON: %s' % (response.status_code, response.json()))
Source files for this sample: utils.py, query-sss.py
require_relative 'utils.rb'
require 'faraday'
utils = Utils.new('dc=com/dc=example/ou=People/uid=kvaughan', 'bribery')
options = { ca_file: utils.ca_pem }
jwt = utils.authenticate
query = {
"_fields": "cn",
"_queryFilter": "sn co 'barnes'",
"_sortKeys": "-givenName",
"scope": "sub"
}
hdap = Faraday.new(url: "https://#{utils.host}:#{utils.port}/hdap/", params: query, ssl: options) do |f|
f.headers['Content-Type'] = 'application/json'
f.request :authorization, 'Bearer', jwt
end
response = hdap.get('dc=com/dc=example/ou=People')
puts "Status code: #{response.status}\nJSON: #{response.body}"
Source files for this sample: utils.rb, query-sss.rb
HDAP Ruby examples require Ruby 3.2 and the faraday
and json
gems.
Show results
{
"result" : [ {
"_id" : "dc=com/dc=example/ou=People/uid=user.94561",
"_rev" : "<revision>",
"cn" : [ "Atsushi Barnes" ]
}, {
"_id" : "dc=com/dc=example/ou=People/uid=user.81142",
"_rev" : "<revision>",
"cn" : [ "Atsuo Barnes" ]
}, {
"_id" : "dc=com/dc=example/ou=People/uid=user.67723",
"_rev" : "<revision>",
"cn" : [ "Atmane Barnes" ]
}, {
"_id" : "dc=com/dc=example/ou=People/uid=user.54304",
"_rev" : "<revision>",
"cn" : [ "Atlante Barnes" ]
}, {
"_id" : "dc=com/dc=example/ou=People/uid=user.40885",
"_rev" : "<revision>",
"cn" : [ "Atlanta Barnes" ]
}, {
"_id" : "dc=com/dc=example/ou=People/uid=user.27466",
"_rev" : "<revision>",
"cn" : [ "Atl-Sales Barnes" ]
}, {
"_id" : "dc=com/dc=example/ou=People/uid=user.14047",
"_rev" : "<revision>",
"cn" : [ "Atl Barnes" ]
}, {
"_id" : "dc=com/dc=example/ou=People/uid=user.628",
"_rev" : "<revision>",
"cn" : [ "Atique Barnes" ]
}, {
"_id" : "dc=com/dc=example/ou=People/uid=abarnes",
"_rev" : "<revision>",
"cn" : [ "Anne-Louise Barnes" ]
} ],
"resultCount" : 9,
"pagedResultsCookie" : null,
"totalPagedResultsPolicy" : "NONE",
"totalPagedResults" : -1,
"remainingPagedResults" : -1
}
-
To specify multiple sort keys, use a comma-separated list of fields.
-
The sort key fields you specify must exist in the result entries.
You do not need to include the sort field(s) in the results.
-
VLV for paged server-side sort shows an HDAP query using a browsing index.
HDAP stores the entire result set before sorting the results. If you expect a large result set for your search, use paged results to limit the performance cost and get results quickly.