James,

Thanks for this. I think I covered this in section 10 of the draft, though probably not in as much detail as needed.

Yes, this is one path forward but it does not provide the functionality as advertised in the RFC and is a lot machinery just to replicate the "remarks" feature of core RDAP, albeit with less functionality as "remarks" can be associated directly with an RDAP object and can provide descriptive text in multiple languages (unlike "redaction").

As Gavin pointed out, such an approach does not work well with clients that do not present the data in a linear style (rdap.org, search.arin.net/rdap, etc...).

When time permits, I'll update the draft to more thoroughly cover this topic.

-andy

On 6/14/24 13:22, Gould, James wrote:

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/&gt;>

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&gt;>

>

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>>


_______________________________________________
regext mailing list -- regext@ietf.org
To unsubscribe send an email to regext-le...@ietf.org

Reply via email to