Skip to content

Commit

Permalink
Add several changes to comply with ICANN RDAP profile feb19
Browse files Browse the repository at this point in the history
fix #84
  • Loading branch information
dhfelix committed Mar 11, 2019
1 parent fd52c6b commit 8373b63
Show file tree
Hide file tree
Showing 13 changed files with 245 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -45,6 +46,8 @@ public class RdapConfiguration {
private static final String NOTICES_TIMER_UPDATE_TIME_KEY = "notices_timer_update_time";
private static final String EVENTS_TIMER_UPDATE_TIME_KEY = "events_timer_update_time";
private static final String IS_DB_DATA_LIVE = "is_db_data_live";
private static final String ADD_CUSTOM_CONFORMANCE_KEY = "add_custom_conformance";
private static final String ADD_EMAIL_REMARK_KEY = "add_email_remark";


// Settings values
Expand All @@ -61,6 +64,9 @@ public class RdapConfiguration {
private static int noticesUpdateTime;
private static int eventsUpdateTime;
private static boolean isDbDataLive;
private static List<String> customConformance;
private static boolean addEmailRemark;


private RdapConfiguration() {
// no code.
Expand Down Expand Up @@ -269,6 +275,26 @@ public static void loadRdapConfiguration() throws InitializationException {
}
}

if (isPropertyNullOrEmpty(ADD_CUSTOM_CONFORMANCE_KEY)) {
customConformance = Collections.emptyList();
} else {
String customConformanceString = systemProperties.getProperty(ADD_CUSTOM_CONFORMANCE_KEY).trim();
customConformance = Collections.unmodifiableList(parseConformances(customConformanceString));
}

if (isPropertyNullOrEmpty(ADD_EMAIL_REMARK_KEY)) {
invalidProperties.add(ADD_EMAIL_REMARK_KEY);
} else {
String addEmailRemarkString = systemProperties.getProperty(ADD_EMAIL_REMARK_KEY).trim();
if (addEmailRemarkString.equalsIgnoreCase("true")) {
addEmailRemark = true;
} else if (addEmailRemarkString.equalsIgnoreCase("false")) {
addEmailRemark = false;
} else {
invalidProperties.add(ADD_EMAIL_REMARK_KEY);
}
}

if (!invalidProperties.isEmpty()) {
InitializationException invalidValueException = new InitializationException(
"The following required properties were not found or are invalid values in configuration file : "
Expand All @@ -280,9 +306,22 @@ public static void loadRdapConfiguration() throws InitializationException {
}

isNSSharingNameConformance = false;



}

private static List<String> parseConformances(String plainString) {
plainString = plainString.trim();
List<String> result = new ArrayList<String>();
String[] split = plainString.split(",");

for (String conformance : split) {
conformance = conformance.trim();
if (conformance.isEmpty())
continue;

result.add(conformance);
}

return result;
}

/**
Expand Down Expand Up @@ -486,4 +525,12 @@ public static int getNoticesUpdateTime() {
public static boolean isDbDataLive() {
return isDbDataLive;
}

public static List<String> getCustomConformances() {
return customConformance;
}

public static boolean addEmailRemark() {
return addEmailRemark;
}
}
12 changes: 7 additions & 5 deletions src/main/java/mx/nic/rdap/server/notices/RequestNotices.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,35 +73,37 @@ static void init(String userPath) throws SAXException, IOException, ParserConfig
domainNotices = NoticesReader.parseNoticesXML(Paths.get(userPath, DOMAIN_FILE_NAME).toString());
} catch (FileNotFoundException | NoSuchFileException e) {
// Nothing happens, continue
logger.log(Level.INFO, "Optional File '" + DOMAIN_FILE_NAME + "' not found, continue.", e);
logger.log(Level.INFO,
"Optional File '" + DOMAIN_FILE_NAME + "' not found, continue. \n\t" + e);
}

try {
entityNotices = NoticesReader.parseNoticesXML(Paths.get(userPath, ENTITY_FILE_NAME).toString());
} catch (FileNotFoundException | NoSuchFileException e) {
// Nothing happens, continue
logger.log(Level.INFO, "Optional File '" + ENTITY_FILE_NAME + "' not found, continue.", e);
logger.log(Level.INFO, "Optional File '" + ENTITY_FILE_NAME + "' not found, continue. \n\t" + e);
}

try {
nsNotices = NoticesReader.parseNoticesXML(Paths.get(userPath, NS_FILE_NAME).toString());
} catch (FileNotFoundException | NoSuchFileException e) {
// Nothing happens, continue
logger.log(Level.INFO, "Optional File '" + NS_FILE_NAME + "' not found, continue.", e);
logger.log(Level.INFO, "Optional File '" + NS_FILE_NAME + "' not found, continue. \n\t" + e);
}

try {
autnumNotices = NoticesReader.parseNoticesXML(Paths.get(userPath, AUTNUM_FILE_NAME).toString());
} catch (FileNotFoundException | NoSuchFileException e) {
// Nothing happens, continue
logger.log(Level.INFO, "Optional File '" + AUTNUM_FILE_NAME + "' not found, continue.", e);
logger.log(Level.INFO, "Optional File '" + AUTNUM_FILE_NAME + "' not found, continue. \n\t" + e);
}

try {
ipNotices = NoticesReader.parseNoticesXML(Paths.get(userPath, IP_NETWORK_FILE_NAME).toString());
} catch (FileNotFoundException | NoSuchFileException e) {
// Nothing happens, continue
logger.log(Level.INFO, "Optional File '" + IP_NETWORK_FILE_NAME + "' not found, continue.", e);
logger.log(Level.INFO,
"Optional File '" + IP_NETWORK_FILE_NAME + "' not found, continue. \n\t" + e);
}

if (RdapConfiguration.getNoticesUpdateTime() > 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/mx/nic/rdap/server/notices/UserEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ static void init(String userPath) throws SAXException, IOException, ParserConfig
userEvents = NoticesReader.parseEventsXML(Paths.get(userPath, EVENT_FILE_NAME).toString());
} catch (FileNotFoundException | NoSuchFileException e) {
// Nothing happens, continue
logger.log(Level.INFO, "Optional File '" + EVENT_FILE_NAME + "' not found, continue.", e);
logger.log(Level.INFO, "Optional File '" + EVENT_FILE_NAME + "' not found, continue. \n\t" + e);
}

if (RdapConfiguration.getEventsUpdateTime() > 0) {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/mx/nic/rdap/server/notices/UserNotices.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,15 @@ public static void init(String userPath, boolean isDefaultPath) throws SAXExcept
tos = NoticesReader.parseTOSXML(Paths.get(userPath, TOS_FILE_NAME).toString());
} catch (FileNotFoundException | NoSuchFileException e) {
// Nothing happens, continue
logger.log(Level.INFO, "Optional File '" + TOS_FILE_NAME + "' not found, continue. \n\t" + e);
}

// The notices are optional.
try {
notices = NoticesReader.parseNoticesXML(Paths.get(userPath, NOTICES_FILE_NAME).toString());
} catch (FileNotFoundException | NoSuchFileException e) {
// Nothing happens, continue
logger.log(Level.INFO, "Optional File '" + NOTICES_FILE_NAME + "' not found, continue. \n\t" + e);
}

RequestNotices.init(userPath);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package mx.nic.rdap.server.privacy;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
Expand All @@ -9,6 +10,8 @@

import mx.nic.rdap.core.catalog.Role;
import mx.nic.rdap.core.db.Entity;
import mx.nic.rdap.core.db.Remark;
import mx.nic.rdap.core.db.RemarkDescription;
import mx.nic.rdap.core.db.VCard;
import mx.nic.rdap.core.db.VCardPostalInfo;
import mx.nic.rdap.server.util.PrivacyUtil;
Expand Down Expand Up @@ -190,12 +193,40 @@ public static boolean filterAnidatedEntities(List<Entity> entities, UserInfo use
}

for (Entity e : entities) {
isPrivate |= filterEntity(e, userInfo);
boolean isRedacted = filterEntity(e, userInfo);
addRedactedForPrivacy(isRedacted, e);
isPrivate |= isRedacted;
}

return isPrivate;
}

/*
* Rdap response profile feb-19 2.7.4.3
* https://www.icann.org/en/system/files/files/rdap-response-profile-15feb19-en.
* pdf
*/
private static void addRedactedForPrivacy(boolean isRedacted, Entity e) {
if (!isRedacted)
return;

if (e.getRemarks() == null)
e.setRemarks(new ArrayList<>());

Remark r = new Remark();
r.setTitle("REDACTED FOR PRIVACY");
r.setType("object redacted due to authorization.");

RemarkDescription rd = new RemarkDescription();
rd.setDescription("Some of the data in this object has been removed.");
rd.setOrder(1);
rd.setRemarkId(1L);

r.getDescriptions().add(rd);

e.getRemarks().add(r);
}

private static boolean filterVcard(VCard vcard, UserInfo userInfo, List<Role> entityRoles) {
if (entityRoles == null || entityRoles.isEmpty()) {
return filterVcard(vcard, userInfo, PrivacyUtil.getVCardPrivacySettings());
Expand Down
9 changes: 7 additions & 2 deletions src/main/java/mx/nic/rdap/server/result/DomainResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,16 @@ public void validateResponse() {
* Generates a link with the self information and add it to the domain
*/
public static void addSelfLinks(String header, String contextPath, Domain domain) {
Link self = new Link(header, contextPath, "domain", domain.getFQDN());
String domainName = domain.getFQDN() != null ? domain.getFQDN() : domain.getUnicodeFQDN();

Link self = new Link(header, contextPath, "domain", domainName);
domain.getLinks().add(self);

for (Nameserver ns : domain.getNameServers()) {
self = new Link(header, contextPath, "nameserver", ns.getLdhName());
String nsName = ns.getFqdnLdhName() != null ? ns.getFqdnLdhName()
: ns.getFqdnUnicodeName();

self = new Link(header, contextPath, "nameserver", nsName);
ns.getLinks().add(self);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ public void validateResponse() {
* @param nameserver
*/
public static void addSelfLinks(String header, String contextPath, Nameserver nameserver) {
Link self = new Link(header, contextPath, "nameserver", nameserver.getLdhName());
String nsName = nameserver.getFqdnLdhName() != null ? nameserver.getFqdnLdhName()
: nameserver.getFqdnUnicodeName();

Link self = new Link(header, contextPath, "nameserver", nsName);
nameserver.getLinks().add(self);

for (Entity ent : nameserver.getEntities()) {
Expand Down
55 changes: 52 additions & 3 deletions src/main/java/mx/nic/rdap/server/servlet/DomainServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
import mx.nic.rdap.server.result.RdapResult;
import mx.nic.rdap.server.util.Util;

@WebServlet(name = "domain", urlPatterns = { "/domain/*" })
@WebServlet(name = "domain", urlPatterns = {"/domain/*"})
public class DomainServlet extends DataAccessServlet<DomainDAO> {

private static final long serialVersionUID = 1L;

/**
* Constant value to set the maximum params expected in the URI, this servlet expects: domain
* Constant value to set the maximum params expected in the URI, this servlet
* expects: domain
*/
private static final int MAX_PARAMS_EXPECTED = 1;

Expand All @@ -46,17 +47,65 @@ protected RdapResult doRdapDaGet(HttpServletRequest httpRequest, DomainDAO dao)
try {
label = new DomainLabel(request.getFullRequestValue());
} catch (DomainLabelException e) {
throw new BadRequestException(e);
if (e.getMessage() != null) {
throw new BadRequestException("Bad Request: " + e.getMessage(), e);
} else {
throw new BadRequestException(e);
}
}
Domain domain = dao.getByName(label);
if (domain == null) {
return null;
}

checkResponse(domain, label);

return new DomainResult(Util.getServerUrl(httpRequest), httpRequest.getContextPath(), domain,
Util.getUsername(SecurityUtils.getSubject()));
}

private static void checkResponse(Domain domain, DomainLabel labelRequested) {
boolean isAlabel = labelRequested.isALabel();
String zone = domain.getZone();
String resultToAdd;

if (isAlabel && (domain.getLdhName() == null || domain.getLdhName().isEmpty())) {
resultToAdd = labelRequested.getALabel().trim();
if (zone != null && !zone.isEmpty()) {
resultToAdd = processResultToAdd(zone, resultToAdd);
}

if (resultToAdd.endsWith("."))
resultToAdd = resultToAdd.substring(0, resultToAdd.length() - 1);

domain.setLdhName(resultToAdd);
} else if (!isAlabel && (domain.getUnicodeName() == null || domain.getUnicodeName().isEmpty())) {
resultToAdd = labelRequested.getULabel().trim();
if (zone != null && !zone.isEmpty()) {
resultToAdd = processResultToAdd(zone, resultToAdd);
}

if (resultToAdd.endsWith("."))
resultToAdd = resultToAdd.substring(0, resultToAdd.length() - 1);

domain.setUnicodeName(resultToAdd);
}
}

private static String processResultToAdd(String zone, String resultToSanitize) {
if (resultToSanitize.endsWith("."))
resultToSanitize = resultToSanitize.substring(0, resultToSanitize.length() - 1);

if (zone.endsWith("."))
zone = zone.substring(0, zone.length() - 1);

int lastIndexOf = resultToSanitize.lastIndexOf(zone);
if (lastIndexOf > 0)
resultToSanitize = resultToSanitize.substring(0, lastIndexOf);

return resultToSanitize;
}

private class DomainRequest {

private String fullRequestValue;
Expand Down
32 changes: 29 additions & 3 deletions src/main/java/mx/nic/rdap/server/servlet/NameserverServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import mx.nic.rdap.server.result.RdapResult;
import mx.nic.rdap.server.util.Util;

@WebServlet(name = "nameserver", urlPatterns = { "/nameserver/*" })
@WebServlet(name = "nameserver", urlPatterns = {"/nameserver/*"})
public class NameserverServlet extends DataAccessServlet<NameserverDAO> {

private static final long serialVersionUID = 1L;
Expand Down Expand Up @@ -54,7 +54,10 @@ protected RdapResult doRdapDaGet(HttpServletRequest httpRequest, NameserverDAO d
try {
label = new DomainLabel(request.getName());
} catch (DomainLabelException e) {
throw new BadRequestException(e);
if (e.getMessage() != null)
throw new BadRequestException("Bad Request: " + e.getMessage(), e);
else
throw new BadRequestException(e);
}

Nameserver nameserver = dao.getByName(label);
Expand All @@ -68,15 +71,38 @@ protected RdapResult doRdapDaGet(HttpServletRequest httpRequest, NameserverDAO d
try {
nameserverCount = dao.getNameserverCount(label);
} catch (NotImplementedException e) {
// throw the exception, if conformance is true the DAO must implement getNameserverCount function.
// throw the exception, if conformance is true the DAO must implement
// getNameserverCount function.
throw e;
}
}

checkResponse(nameserver, label);

return new NameserverResult(Util.getServerUrl(httpRequest), httpRequest.getContextPath(), nameserver,
Util.getUsername(SecurityUtils.getSubject()), nameserverCount);
}

private static void checkResponse(Nameserver ns, DomainLabel labelRequested) {
boolean isAlabel = labelRequested.isALabel();
String resultToAdd;

if (isAlabel && (ns.getLdhName() == null || ns.getLdhName().isEmpty())) {
resultToAdd = labelRequested.getALabel().trim();
if (resultToAdd.endsWith("."))
resultToAdd = resultToAdd.substring(0, resultToAdd.length() - 1);

ns.setLdhName(resultToAdd);
} else if (!isAlabel && (ns.getUnicodeName() == null || ns.getUnicodeName().isEmpty())) {
resultToAdd = labelRequested.getULabel().trim();

if (resultToAdd.endsWith("."))
resultToAdd = resultToAdd.substring(0, resultToAdd.length() - 1);

ns.setUnicodeName(resultToAdd);
}
}

private class NameserverRequest {

private String name;
Expand Down
Loading

0 comments on commit 8373b63

Please sign in to comment.