Skip to content

Commit

Permalink
Update Notes and Nomad links to use canonical name for #66. Code is t…
Browse files Browse the repository at this point in the history
…ested, and test cases were updated, but needs practical tests.
  • Loading branch information
JoelProminic committed Nov 9, 2024
1 parent d09fd88 commit 18791f6
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 29 deletions.
54 changes: 44 additions & 10 deletions Super.Human.Portal_Agents/src/main/java/genesis/LinkProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class LinkProcessor

protected String serverAbbr = null;
protected String serverCommon = null;
protected String serverCanonical = null;

protected static final Pattern notesURLPattern = Pattern.compile("notes://([^/]+)/([^?]+.nsf)(?:/[^/?])?(?:.*)?$", Pattern.CASE_INSENSITIVE);
/** Detect a URI based on the protocol only. The rest of the URL does not have to be valid */
Expand Down Expand Up @@ -88,6 +89,7 @@ public void cleanupLink(JSONObject link) {
// initialize local variables for the server, so that it can be overridden by custom servers
String serverAbbr = this.serverAbbr;
String serverCommon = this.serverCommon;
String serverCanonical = this.serverCanonical;
Map<String, String> insertionParameters = new TreeMap<String,String>(this.insertionParameters); // clone - this could be cloned only when updated if this becomes a performance issue.


Expand All @@ -101,6 +103,8 @@ public void cleanupLink(JSONObject link) {
insertionParameters.put("%SERVER_ABBR%", serverAbbr);
serverCommon = getCommonNameSafe(customServer);
insertionParameters.put("%SERVER_COMMON%", serverCommon);
serverCanonical = getCanonicalNameSafe(customServer);
insertionParameters.put("%SERVER_CANONICAL%", serverCanonical);

// Don't update the server name here.
// We could update it to use the clean serverAbbr value if needed
Expand Down Expand Up @@ -138,18 +142,26 @@ public void cleanupLink(JSONObject link) {
}

// TODO: handle the FQDN in a better way? The format is enforces for Super.Human.Installer, but we'll needs something more generic for other servers.
String url = "notes://" + serverCommon + "/" + databaseEnc;
// Add view if available
String view = JSONUtils.getStringSafe(link, "view");
if (!DominoUtils.isValueEmpty(view)) {
try {
url += "/" + URLEncoder.encode(view, "utf-8") + "?OpenView";
}
catch (UnsupportedEncodingException ex) {
getLog().err("Encoding exception: ", ex);
//String url = "notes://" + serverCommon + "/" + databaseEnc;
// Use the canonical name instead of the common name to work around a bug: https://github.com/Moonshine-IDE/Super.Human.Portal/issues/66
// Since this is expected to contain at least one '/' it needs to be escaped
try {
String url = "notes://" + URLEncoder.encode(serverCanonical, "utf-8") + "/" + databaseEnc;
// Add view if available
String view = JSONUtils.getStringSafe(link, "view");
if (!DominoUtils.isValueEmpty(view)) {
try {
url += "/" + URLEncoder.encode(view, "utf-8") + "?OpenView";
}
catch (UnsupportedEncodingException ex) {
getLog().err("Encoding exception for view: ", ex);
}
}
link.put("url", url);
}
catch (UnsupportedEncodingException ex) {
getLog().err("Encoding exception for canonical name: ", ex);
}
link.put("url", url);
}
// else: url was already set "properly", so keep the original value

Expand Down Expand Up @@ -255,6 +267,8 @@ protected void initializeInsertionParameters(Database configDatabase) {
addInsertionParameter("%SERVER_ABBR%", serverAbbr);
serverCommon = nameObj.getCommon();
addInsertionParameter("%SERVER_COMMON%", serverCommon);
serverCanonical = nameObj.getCanonical();
addInsertionParameter("%SERVER_CANONICAL%", serverCanonical);
}
catch (NotesException ex) {
getLog().err("Exception in initializeInsertionParameters. They will be skipped: ", ex);
Expand Down Expand Up @@ -295,6 +309,9 @@ protected String getAbbrNameSafe(String name) {
log.err("Failed to generate abbreviated name for '" + name + "'. Returning default value: ", ex);
return "UNKNOWN";
}
finally {
DominoUtils.recycle(session, nameObj);
}
}
protected String getCommonNameSafe(String name) {
Name nameObj = null;
Expand All @@ -306,6 +323,23 @@ protected String getCommonNameSafe(String name) {
log.err("Failed to generate common name for '" + name + "'. Returning default value: ", ex);
return "UNKNOWN";
}
finally {
DominoUtils.recycle(session, nameObj);
}
}
protected String getCanonicalNameSafe(String name) {
Name nameObj = null;
try {
nameObj = session.createName(name);
return nameObj.getCanonical();
}
catch (NotesException ex) {
log.err("Failed to generate common name for '" + name + "'. Returning default value: ", ex);
return "UNKNOWN";
}
finally {
DominoUtils.recycle(session, nameObj);
}
}

public void addInsertionParameter(String param, String replacement) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ class LinkProcessorSpec extends Specification {
then:
JSONUtils.getStringSafe(testLink, 'name') == 'NotesDatabase Link'
JSONUtils.getStringSafe(testLink, 'type') == 'database'
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCommon}/dombackup.nsf"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCommon}/dombackup.nsf"
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCanonicalEscaped}/dombackup.nsf"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCanonicalEscaped}/dombackup.nsf"
JSONUtils.getStringSafe(testLink, 'database') == 'dombackup.nsf'
JSONUtils.getStringSafe(testLink, 'server') == test.serverAbbr
!JSONUtils.getStringSafe(testLink, 'view')
Expand All @@ -88,8 +88,8 @@ class LinkProcessorSpec extends Specification {
then:
JSONUtils.getStringSafe(testLink, 'name') == 'NotesDatabase Link'
JSONUtils.getStringSafe(testLink, 'type') == 'database'
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCommon}/actual.nsf"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCommon}/actual.nsf"
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCanonicalEscaped}/actual.nsf"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCanonicalEscaped}/actual.nsf"
JSONUtils.getStringSafe(testLink, 'database') == 'actual.nsf'
JSONUtils.getStringSafe(testLink, 'server') == test.serverAbbr
!JSONUtils.getStringSafe(testLink, 'view')
Expand All @@ -102,7 +102,7 @@ class LinkProcessorSpec extends Specification {
JSONObject testLink = new JSONObject("""{
"name": "NotesDatabase Link",
"type": "database",
"url": "notes://${test.serverCommon}/dombackup.nsf",
"url": "notes://${test.serverCommon}/dombackup.nsf",
"database": "actual.nsf"
}""")
test.cleanupLink(testLink);
Expand Down Expand Up @@ -130,8 +130,8 @@ class LinkProcessorSpec extends Specification {
then:
JSONUtils.getStringSafe(testLink, 'name') == 'NotesDatabase Link'
JSONUtils.getStringSafe(testLink, 'type') == 'database'
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCommon}/dom+backup.nsf"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCommon}/dom+backup.nsf"
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCanonicalEscaped}/dom+backup.nsf"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCanonicalEscaped}/dom+backup.nsf"
JSONUtils.getStringSafe(testLink, 'database') == 'dom backup.nsf'
JSONUtils.getStringSafe(testLink, 'server') == test.serverAbbr
!JSONUtils.getStringSafe(testLink, 'view')
Expand All @@ -153,8 +153,8 @@ class LinkProcessorSpec extends Specification {
then:
JSONUtils.getStringSafe(testLink, 'name') == 'NotesDatabase Link'
JSONUtils.getStringSafe(testLink, 'type') == 'database'
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCommon}/dombackup.nsf/TestView?OpenView"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCommon}/dombackup.nsf/TestView?OpenView"
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCanonicalEscaped}/dombackup.nsf/TestView?OpenView"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCanonicalEscaped}/dombackup.nsf/TestView?OpenView"
JSONUtils.getStringSafe(testLink, 'database') == 'dombackup.nsf'
JSONUtils.getStringSafe(testLink, 'server') == test.serverAbbr
JSONUtils.getStringSafe(testLink, 'view') == "TestView"
Expand All @@ -175,8 +175,8 @@ class LinkProcessorSpec extends Specification {
then:
JSONUtils.getStringSafe(testLink, 'name') == 'NotesDatabase Link'
JSONUtils.getStringSafe(testLink, 'type') == 'database'
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCommon}/dombackup.nsf/8.+Config?OpenView"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCommon}/dombackup.nsf/8.+Config?OpenView"
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCanonicalEscaped}/dombackup.nsf/8.+Config?OpenView"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCanonicalEscaped}/dombackup.nsf/8.+Config?OpenView"
JSONUtils.getStringSafe(testLink, 'database') == 'dombackup.nsf'
JSONUtils.getStringSafe(testLink, 'server') == test.serverAbbr
JSONUtils.getStringSafe(testLink, 'view') == "8. Config"
Expand All @@ -197,8 +197,8 @@ class LinkProcessorSpec extends Specification {
then:
JSONUtils.getStringSafe(testLink, 'name') == 'NotesDatabase Link'
JSONUtils.getStringSafe(testLink, 'type') == 'database'
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCommon}/test%2Fdombackup.nsf/foo%5Cbar%5Ctestview?OpenView"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCommon}/test%2Fdombackup.nsf/foo%5Cbar%5Ctestview?OpenView"
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCanonicalEscaped}/test%2Fdombackup.nsf/foo%5Cbar%5Ctestview?OpenView"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCanonicalEscaped}/test%2Fdombackup.nsf/foo%5Cbar%5Ctestview?OpenView"
JSONUtils.getStringSafe(testLink, 'database') == 'test/dombackup.nsf'
JSONUtils.getStringSafe(testLink, 'server') == test.serverAbbr
JSONUtils.getStringSafe(testLink, 'view') == "foo\\bar\\testview"
Expand All @@ -222,8 +222,8 @@ class LinkProcessorSpec extends Specification {
then:
JSONUtils.getStringSafe(testLink, 'name') == "Test Insertion: '${test.serverAbbr}', '${test.serverCommon}'"
JSONUtils.getStringSafe(testLink, 'type') == 'database'
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCommon}/dombackup.nsf/TestView?OpenView"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCommon}/dombackup.nsf/TestView?OpenView"
JSONUtils.getStringSafe(testLink, 'url') == "notes://${test.serverCanonicalEscaped}/dombackup.nsf/TestView?OpenView"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://${test.serverCanonicalEscaped}/dombackup.nsf/TestView?OpenView"
JSONUtils.getStringSafe(testLink, 'database') == 'dombackup.nsf'
JSONUtils.getStringSafe(testLink, 'server') == test.serverAbbr
JSONUtils.getStringSafe(testLink, 'view') == "TestView"
Expand All @@ -250,8 +250,8 @@ class LinkProcessorSpec extends Specification {

JSONUtils.getStringSafe(testLink, 'name') == "Test Insertion: 'test/TEST', 'test'"
JSONUtils.getStringSafe(testLink, 'type') == 'database'
JSONUtils.getStringSafe(testLink, 'url') == "notes://test/dombackup.nsf/TestView?OpenView"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://test/dombackup.nsf/TestView?OpenView"
JSONUtils.getStringSafe(testLink, 'url') == "notes://CN%3Dtest%2FO%3DTEST/dombackup.nsf/TestView?OpenView"
JSONUtils.getStringSafe(testLink, 'nomadURL') == "https://nomadweb.${test.serverCommon}/nomad/#/notes://CN%3Dtest%2FO%3DTEST/dombackup.nsf/TestView?OpenView"
JSONUtils.getStringSafe(testLink, 'database') == 'dombackup.nsf'
JSONUtils.getStringSafe(testLink, 'server') == 'test/TEST'
JSONUtils.getStringSafe(testLink, 'view') == "TestView"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import util.ValidationException;
public class LinkProcessorTest extends LinkProcessor {
private JSONArray testData = null;

protected String serverCanonicalEscaped = null;

public LinkProcessorTest() {
super(null, new DefaultLogInterface(), null);
initializeInsertionParameters();
Expand All @@ -31,8 +33,11 @@ public class LinkProcessorTest extends LinkProcessor {
protected void initializeInsertionParameters(Database configDatabase) {
serverAbbr = 'test-1.test.com/test';
serverCommon = 'test-1.test.com';
addInsertionParameter("%SERVER_ABBR%", serverAbbr);
addInsertionParameter("%SERVER_COMMON%", serverCommon);
serverCanonical = 'CN=test-1.test.com/O=test';
serverCanonicalEscaped = 'CN%3Dtest-1.test.com%2FO%3Dtest';
addInsertionParameter("%SERVER_ABBR%", serverAbbr);
addInsertionParameter("%SERVER_COMMON%", serverCommon);
addInsertionParameter("%SERVER_CANONICAL%", serverCanonical);
}

protected void setTestData(JSONArray testData) {
Expand Down Expand Up @@ -61,4 +66,10 @@ public class LinkProcessorTest extends LinkProcessor {
// simplified solution to work with test case
return name.replaceAll('^(.*)/(.*)$', '$1');
}

@Override // remove Notes API reference
protected String getCanonicalNameSafe(String name) {
// simplified solution to work with test case
return name.replaceAll('^(.*)/(.*)$', 'CN=$1/O=$2');
}
}

0 comments on commit 18791f6

Please sign in to comment.