From 593a589636dd906c9fafc3830805d7195d69310e Mon Sep 17 00:00:00 2001 From: Seamus Johnston Date: Mon, 5 Jun 2023 08:54:48 -0500 Subject: [PATCH 1/5] Add developer documentation for EPP --- docs/developer/registry-access.md | 101 ++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 docs/developer/registry-access.md diff --git a/docs/developer/registry-access.md b/docs/developer/registry-access.md new file mode 100644 index 000000000..3f5d06c09 --- /dev/null +++ b/docs/developer/registry-access.md @@ -0,0 +1,101 @@ +# Working with the registry via EPP + +## Overview of parts + +**EPP** is the protocol which describes how a registry and registrar communicate with XML over a TCP socket connection. + +**epplib** is a Python library implementation of the TCP socket connection. It has helper functions and dataclasses which can be used to send and receive the XML messages. + +**epplibwrapper** is a module in this repository which abstracts away the details of authenticating with the registry. It assists with error handling by providing error code constants and an error class with some helper methods. + +**Domain** is a Python class. It inherits from `django.db.models.Model` and is therefore part of Django's ORM and has a corresponding table in the local registrar database. Its purpose is to provide a developer-friendly interface to the registry based on *what a registrant or analyst wants to do*, not on the technical details of EPP. + +## Debugging in a Python shell + +You'll first need access to a Django shell in an environment with valid registry credentials. For example: + +```shell +cf ssh getgov-ENVIRONMENT +/tmp/lifecycle/shell # this configures your environment +./manage.py shell +``` + +You'll next need to import some code. + +``` +from epplibwrapper import CLIENT as registry, commands +from epplib.models import common +``` + +Finally, you'll need to craft a request and send it. + +``` +request = ... +response = registry.send(request) +``` + +See below for some example commands to send. Replace example data with data which makes sense for your debugging scenario. Other commands are available; see the source code of epplib for more options. + + +### Get info about a contact + +``` +request = commands.InfoContact(id='sh8013') +``` + +### Create a new contact + +``` +DF = common.DiscloseField +di = common.Disclose(flag=False, fields={DF.FAX, DF.VOICE, DF.ADDR}, types={DF.ADDR: "loc"}) +addr = common.ContactAddr(street=['123 Example Dr.'], city='Dulles', pc='20166-6503', cc='US', sp='VA') +pi = common.PostalInfo(name='John Doe', addr=addr, org="Example Inc.", type="loc") +ai = common.ContactAuthInfo(pw='feedabee') + +request = commands.CreateContact(id='sh8013', postal_info=pi, email='jdoe@example.com', voice='+1.7035555555', fax='+1.7035555556', auth_info=ai, disclose=di, vat=None, ident=None, notify_email=None) +``` + +### Create a new domain + +``` +ai = common.DomainAuthInfo(pw='feedabee') +request = commands.CreateDomain(name="okay.gov", registrant="sh8013", auth_info=ai) +``` + +### Create a host object + +``` +request = commands.CreateHost(name="ns1.okay.gov", addrs=[common.Ip(addr="127.0.01"), common.Ip(addr="0:0:0:0:0:0:0:1", ip="v6")]) +``` + +### Check if a host is available + +``` +request = commands.CheckHost(["ns2.okay.gov"]) +``` + +### Update a domain + +``` +request = commands.UpdateDomain(name="okay.gov", add=[common.HostObjSet(["ns1.okay.gov"])]) +``` + +``` +request = commands.UpdateDomain(name="okay.gov", add=[common.DomainContact(contact="sh8014", type="technical")]) +``` + +### How to see the raw XML + +To see the XML of a command before the request is sent, call `request.xml()`. + +To see the XML of the response, you must send the command using a different method. + +``` +registry._client.connect() +registry._client.send(registry._login) + +request = commands.InfoDomain(name="ok.gov") + +registry._client.transport.send(request.xml()) +response = registry._client.transport.receive() +``` From 28fde240104c55d924314f29b04c4e37377163cd Mon Sep 17 00:00:00 2001 From: Seamus Johnston Date: Wed, 7 Jun 2023 15:40:25 -0500 Subject: [PATCH 2/5] Update docs/developer/registry-access.md Co-authored-by: Alysia Broddrick <109625347+abroddrick@users.noreply.github.com> --- docs/developer/registry-access.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer/registry-access.md b/docs/developer/registry-access.md index 3f5d06c09..a438d565d 100644 --- a/docs/developer/registry-access.md +++ b/docs/developer/registry-access.md @@ -81,7 +81,7 @@ request = commands.UpdateDomain(name="okay.gov", add=[common.HostObjSet(["ns1.ok ``` ``` -request = commands.UpdateDomain(name="okay.gov", add=[common.DomainContact(contact="sh8014", type="technical")]) +request = commands.UpdateDomain(name="okay.gov", add=[common.DomainContact(contact="sh8014", type="tech")]) ``` ### How to see the raw XML From 0bd07bb8ed2ab1982379ff9c6d1a93c90f0d1e14 Mon Sep 17 00:00:00 2001 From: Seamus Johnston Date: Wed, 7 Jun 2023 15:40:40 -0500 Subject: [PATCH 3/5] Update docs/developer/registry-access.md Co-authored-by: Alysia Broddrick <109625347+abroddrick@users.noreply.github.com> --- docs/developer/registry-access.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer/registry-access.md b/docs/developer/registry-access.md index a438d565d..4ec5440dd 100644 --- a/docs/developer/registry-access.md +++ b/docs/developer/registry-access.md @@ -65,7 +65,7 @@ request = commands.CreateDomain(name="okay.gov", registrant="sh8013", auth_info= ### Create a host object ``` -request = commands.CreateHost(name="ns1.okay.gov", addrs=[common.Ip(addr="127.0.01"), common.Ip(addr="0:0:0:0:0:0:0:1", ip="v6")]) +request = commands.CreateHost(name="ns1.okay.gov", addrs=[common.Ip(addr="127.0.0.1"), common.Ip(addr="0:0:0:0:0:0:0:1", ip="v6")]) ``` ### Check if a host is available From 72fe97717883827b20a8e8948c9b3132b58103e7 Mon Sep 17 00:00:00 2001 From: Seamus Johnston Date: Thu, 8 Jun 2023 11:12:07 -0500 Subject: [PATCH 4/5] Respond to PR feedback --- docs/developer/registry-access.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/developer/registry-access.md b/docs/developer/registry-access.md index 4ec5440dd..d2df556e9 100644 --- a/docs/developer/registry-access.md +++ b/docs/developer/registry-access.md @@ -12,7 +12,7 @@ ## Debugging in a Python shell -You'll first need access to a Django shell in an environment with valid registry credentials. For example: +You'll first need access to a Django shell in an environment with valid registry credentials. Only some environments are allowed access: your laptop is probably not one of them. For example: ```shell cf ssh getgov-ENVIRONMENT @@ -99,3 +99,5 @@ request = commands.InfoDomain(name="ok.gov") registry._client.transport.send(request.xml()) response = registry._client.transport.receive() ``` + +This is helpful for debugging situations where epplib is not correctly or fully parsing the XML returned from the registry. From 3d6fe6a6290f8b6752c9509fb20b88c82279687d Mon Sep 17 00:00:00 2001 From: Seamus Johnston Date: Fri, 9 Jun 2023 07:37:15 -0500 Subject: [PATCH 5/5] Add note about cleaned flag --- docs/developer/registry-access.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/developer/registry-access.md b/docs/developer/registry-access.md index d2df556e9..a59c8b8b7 100644 --- a/docs/developer/registry-access.md +++ b/docs/developer/registry-access.md @@ -34,6 +34,8 @@ request = ... response = registry.send(request) ``` +Note that you'll need to attest that the data you are sending has been sanitized to remove malicious or invalid strings. Use `send(..., cleaned=True)` to do that. + See below for some example commands to send. Replace example data with data which makes sense for your debugging scenario. Other commands are available; see the source code of epplib for more options.