Andy,
To help, I provide a couple simple example clients that leverage the
required "name" and "method" members to print / display the redactions
of Figure 12 "Redacted RDAP Lookup Response" of the RFC. These
programs are executed on the command line against a passed in RDAP
response, but the code could be plugged into an RDAP REST client.
There are many ways for a client to display the list of redactions and
key off the redacted "name" member to provide a visual indication
elsewhere in the display. Let me know if you have any questions or
feedback with implementing your clients.
*RDAPRedactedPrint*
Description:
Provide a simple listing of the redactions to the user by including
the required "name" member, the required "method" member, and the
optional "reason" member.
Code:
importjava.io.File;
importjava.io.IOException;
importcom.fasterxml.jackson.databind.JsonNode;
importcom.fasterxml.jackson.databind.ObjectMapper;
publicclassRDAPRedactedPrint{
publicstaticvoidmain(String[] args) {
try{
JsonNoderootNode=newObjectMapper().readTree(newFile(args[0]));
JsonNoderedactedExt=rootNode.get("redacted");
if(redactedExt !=null&&redactedExt.isArray()) {
for(JsonNoderedacted:redactedExt) {
// Name
Stringname;
name =redacted.get("name").get("description").asText();
if(name ==null) {
name =redacted.get("name").get("type").asText();
}
// Method
Stringmethod="removal";
if(redacted.get("method") !=null) {
method =redacted.get("method").asText();
}
System.out.print("name: \""+name +"\", method: "+method);
// Reason
Stringreason=null;
if(redacted.get("reason") !=null) {
reason =redacted.get("reason").get("description").asText();
if(reason ==null) {
reason =redacted.get("reason").get("type").asText();
}
System.out.print(", reason: \""+reason +"\"");
}
System.out.println();
}
}
} catch(IOExceptione) {
System.err.println("Exception: "+e);
}
}
}
Output:
name: "Registry Domain ID", method: removal, reason: "Server policy"
name: "Registrant Name", method: emptyValue, reason: "Server policy"
name: "Registrant Organization", method: removal, reason: "Server policy"
name: "Registrant Street", method: emptyValue, reason: "Server policy"
name: "Registrant City", method: emptyValue, reason: "Server policy"
name: "Registrant Postal Code", method: emptyValue, reason: "Server
policy"
name: "Registrant Email", method: removal, reason: "Server policy"
name: "Registrant Phone", method: removal, reason: "Server policy"
name: "Technical Name", method: emptyValue, reason: "Server policy"
name: "Technical Email", method: removal, reason: "Server policy"
name: "Technical Phone", method: removal, reason: "Server policy"
name: "Technical Fax", method: removal, reason: "Client request"
name: "Administrative Contact", method: removal, reason: "Refer to the
technical contact"
name: "Billing Contact", method: removal, reason: "Refer to the
registrant contact"
*RDAPRedactedMethodPrint*
Description:
Provide a listing of the redactions grouped by redaction method. The
“removal” and “emptyValue” methods are combined for display to the end
user since there is no concrete difference in the transformed output.
I also only include the “name” member grouped by method, but the
“reason” could optionally be displayed.
Code:
importjava.io.File;
importjava.io.IOException;
importjava.util.ArrayList;
importjava.util.List;
importcom.fasterxml.jackson.databind.JsonNode;
importcom.fasterxml.jackson.databind.ObjectMapper;
publicclassRDAPRedactedMethodPrint{
privatestaticclassRedacted{
publicStringname;
publicStringmethod="removal";
}
publicstaticvoidmain(String[] args) {
try{
JsonNoderootNode=newObjectMapper().readTree(newFile(args[0]));
JsonNoderedactedExt=rootNode.get("redacted");
List<Redacted> removedRedactions=newArrayList<Redacted>();
List<Redacted> partialRedactions=newArrayList<Redacted>();
List<Redacted> replacedRedactions=newArrayList<Redacted>();
// Map redacted member
if(redactedExt !=null&&redactedExt.isArray()) {
for(JsonNoderedactedNode:redactedExt) {
Redactedredacted=newRedacted();
// Name
redacted.name=redactedNode.get("name").get("description").asText();
if(redacted.name==null) {
redacted.name=redactedNode.get("name").get("type").asText();
}
// Method
if(redactedNode.get("method") !=null) {
redacted.method=redactedNode.get("method").asText();
}
if(redacted.method.equals("removal")
||(redacted.method.equals("emptyValue"))) {
removedRedactions.add(redacted);
}
elseif(redacted.method.equals("partialValue")) {
partialRedactions.add(redacted);
}
elseif(redacted.method.equals("replacementValue")) {
replacedRedactions.add(redacted);
}
}
}
// Print redactions grouped by method
if(!removedRedactions.isEmpty()) {
System.out.println("Redacted by Removal:\n");
for(Redactedredacted:removedRedactions) {
System.out.println(redacted.name);
}
}
if(!partialRedactions.isEmpty()) {
System.out.println("Partially Redacted:\n");
for(Redactedredacted:partialRedactions) {
System.out.println(redacted.name);
}
}
if(!replacedRedactions.isEmpty()) {
System.out.println("Redacted by Replacement:\n");
for(Redactedredacted:replacedRedactions) {
System.out.println(redacted.name);
}
}
} catch(IOExceptione) {
System.err.println("Exception: "+e);
}
}
}
Output:
Redacted by Removal:
Registry Domain ID
Registrant Name
Registrant Organization
Registrant Street
Registrant City
Registrant Postal Code
Registrant Email
Registrant Phone
Technical Name
Technical Email
Technical Phone
Technical Fax
Administrative Contact
Billing Contact
--
JG
James Gould
Fellow Engineer
jgo...@verisign.com
<applewebdata://13890C55-AAE8-4BF3-A6CE-B4BA42740803/jgo...@verisign.com>
703-948-3271
12061 Bluemont Way
Reston, VA 20190
Verisign.com <http://verisigninc.com/>
On 6/11/24, 2:02 PM, "Gould, James" <jgo...@verisign.com
<mailto:jgo...@verisign.com>> wrote:
Andy,
The redacted extension provides information to the client of what has
been redacted and it's up to the client to determine how to display
it. The implementer needs to leverage the entire specification of the
RFC, where in section 4.2 ""redacted" Member", it fully defines which
of the members are required and optional. I agree that the abstract
could have been better worded. It's not up to section 3.1 "Redaction
by Removal Method" to define the "prePath" as optional since that's
covered in section 4.2 ""redacted" Member". The inclusion of an
optional member in the example does not change the normative language
in section 4.2.
Is it possible to display the list of redactions to the users using
the required "name" and "method" members? The registered "redacted
name" values should help the clients provide additional visual
indicators if required.
Thanks,
--
JG
James Gould
Fellow Engineer
jgo...@verisign.com <mailto:jgo...@verisign.com>
<applewebdata://13890C55-AAE8-4BF3-A6CE-B4BA42740803/jgo...@verisign.com
<mailto:jgo...@verisign.com>>
703-948-3271
12061 Bluemont Way
Reston, VA 20190
Verisign.com <http://verisigninc.com/> <http://verisigninc.com/>>
On 6/11/24, 10:59 AM, "Andrew Newton (andy)" <a...@hxr.us
<mailto:a...@hxr.us> <mailto:a...@hxr.us <mailto:a...@hxr.us>>> wrote:
Caution: This email originated from outside the organization. Do not
click links or open attachments unless you recognize the sender and
know the content is safe.
On 6/11/24 07:57, kowa...@denic.de <mailto:kowa...@denic.de>
<mailto:kowa...@denic.de <mailto:kowa...@denic.de>> wrote:
>
> Hi,
>
> I think the issue of JSONPath not being easy/possible to interpret in
> case of removed paths was brought up on the mailing list and the
> conclusion was to key off the "redacted name" rather than base on
> JSONPath [1].
>
> This is also what has been covered in 5.1.1 with a clear
> recommendation for the client implementers. Not enough?
>
> [1]
>
https://secure-web.cisco.com/13EK5pT1XZj4x6yjYjnZ_zLex4bki3NGhJbBSsKe9nSP7lApyLcWFL5KLe93xmfHQXF5B_VVpCG10_frgBqZa8dSFH_P2Mq-ltn9GWApbm3LsiRN5SeeugfyofTnr6wOa9w4tpIiF_3RSGrRkWCAKYEvIN7aEVNmBB_pjsTGOsV7Ap1aRObLzqp4o-RQ6rTRchaaokaYz0XYGQYrlm_p5t38RvHglH2pS62WCMkXQCCqEI-W50CWZWJt6fHH60h-w8tkEZ2HZQnKHyB0SkdAUANirvrAQAih-5Ila-_rVBrQ/https%3A%2F%2Fmailarchive.ietf.org%2Farch%2Fmsg%2Fregext%2FnP9BZFbwhOkgiMim9s5upRqCYRs%2F
<https://secure-web.cisco.com/13EK5pT1XZj4x6yjYjnZ_zLex4bki3NGhJbBSsKe9nSP7lApyLcWFL5KLe93xmfHQXF5B_VVpCG10_frgBqZa8dSFH_P2Mq-ltn9GWApbm3LsiRN5SeeugfyofTnr6wOa9w4tpIiF_3RSGrRkWCAKYEvIN7aEVNmBB_pjsTGOsV7Ap1aRObLzqp4o-RQ6rTRchaaokaYz0XYGQYrlm_p5t38RvHglH2pS62WCMkXQCCqEI-W50CWZWJt6fHH60h-w8tkEZ2HZQnKHyB0SkdAUANirvrAQAih-5Ila-_rVBrQ/https%3A%2F%2Fmailarchive.ietf.org%2Farch%2Fmsg%2Fregext%2FnP9BZFbwhOkgiMim9s5upRqCYRs%2F>
<https://secure-web.cisco.com/13EK5pT1XZj4x6yjYjnZ_zLex4bki3NGhJbBSsKe9nSP7lApyLcWFL5KLe93xmfHQXF5B_VVpCG10_frgBqZa8dSFH_P2Mq-ltn9GWApbm3LsiRN5SeeugfyofTnr6wOa9w4tpIiF_3RSGrRkWCAKYEvIN7aEVNmBB_pjsTGOsV7Ap1aRObLzqp4o-RQ6rTRchaaokaYz0XYGQYrlm_p5t38RvHglH2pS62WCMkXQCCqEI-W50CWZWJt6fHH60h-w8tkEZ2HZQnKHyB0SkdAUANirvrAQAih-5Ila-_rVBrQ/https%3A%2F%2Fmailarchive.ietf.org%2Farch%2Fmsg%2Fregext%2FnP9BZFbwhOkgiMim9s5upRqCYRs%2F>
<https://secure-web.cisco.com/13EK5pT1XZj4x6yjYjnZ_zLex4bki3NGhJbBSsKe9nSP7lApyLcWFL5KLe93xmfHQXF5B_VVpCG10_frgBqZa8dSFH_P2Mq-ltn9GWApbm3LsiRN5SeeugfyofTnr6wOa9w4tpIiF_3RSGrRkWCAKYEvIN7aEVNmBB_pjsTGOsV7Ap1aRObLzqp4o-RQ6rTRchaaokaYz0XYGQYrlm_p5t38RvHglH2pS62WCMkXQCCqEI-W50CWZWJt6fHH60h-w8tkEZ2HZQnKHyB0SkdAUANirvrAQAih-5Ila-_rVBrQ/https%3A%2F%2Fmailarchive.ietf.org%2Farch%2Fmsg%2Fregext%2FnP9BZFbwhOkgiMim9s5upRqCYRs%2F>>
>
Section 5 is not normative. And the text says "The client can key off
the "name" member for display logic related to the redaction." But there
is no explanation of how to do it. And the words "display logic" imply
it can be used for an algorithmic method, such as bold red text saying
"REDACTED" where the information would have been placed.
I think any fair reading of this RFC implies the extension provides a
programmatic means using algorithms to "explicitly specify which RDAP
fields are not included in the RDAP response due to redaction" (that is
from section 1, paragraph 1).
The very first prose of this RFC, the abstract, says:
This document describes a Registration Data Access Protocol (RDAP)
extension for specifying methods of redaction of RDAP responses and
explicitly identifying redacted RDAP response fields, using JSONPath as
the default expression language.
WRT to redaction by removal, section 3.1 describes it but does not state
that prePath is optional (that is in section 4.2), and the example given
in 3.1 uses prePath.
-andy
p.s. I just reread the archived message above, and it looks like you
identified these issues two years ago. My apologies for a lack of
understanding back then.
_______________________________________________
regext mailing list -- regext@ietf.org <mailto:regext@ietf.org>
<mailto:regext@ietf.org <mailto:regext@ietf.org>>
To unsubscribe send an email to regext-le...@ietf.org
<mailto:regext-le...@ietf.org> <mailto:regext-le...@ietf.org
<mailto:regext-le...@ietf.org>>