metaregistrar / php-epp-client

Object-oriented PHP EPP Client
https://www.metaregistrar.com/docs/
MIT License
210 stars 155 forks source link

Help: Get ext applicant from domain info request #186

Closed joveice closed 5 years ago

joveice commented 5 years ago

I hope it's okey to ask for help here. To start off, I have little to non experience with EPP.

I'm trying to access the Applicant dataset from a domain at norid (.no).

$conn = new noridEppConnection();
/* all config goes here */

$info = new eppInfoDomainRequest(new noridEppDomain('test.no'));
$response = $conn->request($info);
$d = $response->getDomain();

Here I'm getting $d which is a eppDomain object, I found the noridEppDomain class which has functions related to ext applicant, how do I get this object or the data I'm looking for? I can see it in the raw XML.

metaregistrar commented 5 years ago

The Norid extension was contributed by Alexander Sagen, Github user alexrsagen. I have not really looked into how it works, but maybe you can ask him about the extension.

joveice commented 5 years ago

Hey @alexrsagen mind shining some light on this?

alexrsagen commented 5 years ago

Sure. The simple explanation is that there has not been written any implementation of the Norid response extensions for no-ext-domain:infDataType.

I'll implement this today and create a pull request.

joveice commented 5 years ago

That would be great! Thanks Alexander.

alexrsagen commented 5 years ago

Implemented in PR #187.

Sample use:

$resp = $conn->request(new noridEppInfoDomainRequest(new noridEppDomain('test.no')));
var_dump($resp->getExtApplicantDataset());
// array(5) {
//   ["versionNumber"]=>
//   string(3) "3.0"
//   ["acceptName"]=>
//   string(18) "Ola Nordmann"
//   ["acceptDate"]=>
//   string(23) "2019-05-07T07:42:00.00Z"
//   ["updateClientID"]=>
//   string(7) "reg0"
//   ["updateDate"]=>
//   string(23) "2017-05-07T07:42:00.00Z"
// }
joveice commented 5 years ago

@alexrsagen Worked nicely! Tho, I believe the same is missing for contacts or have I just done something wrong? (Maybe with update too?) I'm looking to do a CRUD on domains and contacts, should it be good for that or does it currently lack the needed features for this?

alexrsagen commented 5 years ago

@joveice It seems like you are misunderstanding something here. Application dataset is only a feature of domains, not contacts.

See Norid's documentation for what data is available on which object types: https://www.norid.no/uploads/2017/11/EPP_Interface_Specification.0e1.pdf (link to latest version of PDF and example XML sequences available on following page: https://www.norid.no/no/registrar/system/dokumentasjon/epp-grensesnitt/)

joveice commented 5 years ago

Yea I know for that one, but I was thinking of contact stuff like contact types and identity types which are also some ext stuff that's not included in the eppContact class but is in noridEppContact class. It just looked to be the same thing as this issue is about the domain just that it was for the contact instead, sorry if I didn't make it clear.

alexrsagen commented 5 years ago

@joveice Indeed this is not implemented for contact info either. Give me a moment, I'll add it and create another PR.

alexrsagen commented 5 years ago

@joveice Fixed in #188.

Sample use:

$resp = $conn->request(new noridEppInfoContactRequest(new eppContactHandle('AB1234O')));
var_dump($resp->getExtIdentity());
// string(9) "123456789"

See https://github.com/Konsept-IT/php-epp-client/blob/0a8953365fbbfa1a99844ae0b306fdb66a863486/Protocols/EPP/eppExtensions/no-ext-contact-1.0/eppResponses/noridEppInfoContactResponse.php for which response methods are added.

joveice commented 5 years ago

Thanks, I'll see how far I'm able to come this time

joveice commented 5 years ago

Works like a charm. Now, I'm unable to update the domain, using eppUpdateDomainRequest, I'm gonna guess there also needs to be a norid specific one here? (I see there is a norid specific for contact update)

alexrsagen commented 5 years ago

@joveice Turn on debug logging and check the errors returned by Norid.

$conn = new noridEppConnection(true);

Norid only requires the use of an extension to the domain update request whenever the owner handle is changed or when nameservers are changed and DNSSEC is enabled.

The extension required will either be the application dataset extension (for owner changes) or the secDNS extension (for nameserver/DNSSEC changes, implemented in eppDnssecUpdateDomainRequest)

I've just now created PR #188 as well, which adds noridEppUpdateDomainRequest (which extends eppDnssecUpdateDomainRequest, so you can do DNSSEC changes with this request too).

joveice commented 5 years ago

Hm, @alexrsagen thanks for the explaination. I tried to update the domain

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <epp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:ietf:params:xml:ns:epp-1.0" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd ▶
      <response>
        <result code="2001">
          <msg>Command syntax error</msg>
        </result>
        <extension>
          <conditions xmlns="http://www.norid.no/xsd/no-ext-result-1.0" xsi:schemaLocation="http://www.norid.no/xsd/no-ext-result-1.0 no-ext-result-1.0.xsd">
            <condition code="EC000015" severity="error">
              <msg>EPP parse error</msg>
              <details>Parse error at line [2], column [1871]: Element '{http://www.norid.no/xsd/no-ext-domain-1.1}applicantDataset': This element is not expected. Expected is ( {http://www.norid.no/xsd/no-ext-domain-1.1}chg ). 
    </details>
            </condition>
          </conditions>
        </extension>
        <trID>
          <svTRID>*not sure if this is sensitive*</svTRID>
        </trID>
      </response>
    </epp>

The link it returned is dead. But it's something with the dataset? I see that the request looks like this:

<extension>
          <no-ext-domain:update>
            <no-ext-domain:applicantDataset>
              <no-ext-domain:versionNumber>2.0</no-ext-domain:versionNumber>
              <no-ext-domain:acceptName/>
              <no-ext-domain:acceptDate/>
            </no-ext-domain:applicantDataset>
          </no-ext-domain:update>
        </extension>

No name, no date. but the noridEppDomain I pass it has it:

  -extApplicantDatasetVersionNumber: "2.0"
  -extApplicantDatasetAcceptName: "*removed*"
  -extApplicantDatasetAcceptDate: "2012-08-21T12:01:34.00Z"

Got a clue?

alexrsagen commented 5 years ago

@joveice The update error is fixed in PR #192. My mistake.

As for your acceptName and acceptDate being empty, I can only assume that the entire dataset is not set on the noridEppDomain at the time of constructing the noridEppUpdateDomainRequest class instance. All applicant dataset values must be set prior to constructing the noridEppUpdateDomainRequest.

joveice commented 5 years ago

Yep, seems like it works, now it complains due to my missing variables. Could you take a look at this and see if you can make any sense of it? because I cannot.

$domain = new noridEppDomain($request->name); //lets say test.no
...
$domain->setExtApplicantDataset($request->version_number, $request->accept_name, $request->accept_date);
...
$update = new noridEppUpdateDomainRequest(new noridEppDomain($request->name), null, null, $domain);

This is correct yea? the $domain looks like this

noridEppDomain {#344 ▼
  -extToken: null
  -extNotifyMobilePhone: null
  -extNotifyEmail: null
  -extDeleteFromDNS: null
  -extDeleteFromRegistry: null
  -extApplicantDatasetVersionNumber: "2.0"
  -extApplicantDatasetAcceptName: "*removed*"
  -extApplicantDatasetAcceptDate: "2012-08-21T12:01:34.00Z"
  -domainname: "test.no"
  -registrant: "*removed*"
  -contacts: array:1 [▶]
  -hosts: array:2 [▶]
  -statuses: []
  -secdns: []
  -authorisationCode: null
  -periodunit: "y"
  -period: 0
}

A dump of $domainfrom in addDomainExtApplicantDataset() in noridEppUpdateDomainRequest.php

noridEppDomain {#345 ▼
  -extToken: null
  -extNotifyMobilePhone: null
  -extNotifyEmail: null
  -extDeleteFromDNS: null
  -extDeleteFromRegistry: null
  -extApplicantDatasetVersionNumber: "2.0"
  -extApplicantDatasetAcceptName: null
  -extApplicantDatasetAcceptDate: null
  -domainname: "test.no"
  -registrant: ""
  -contacts: []
  -hosts: []
  -statuses: []
  -secdns: []
  -authorisationCode: null
  -periodunit: "y"
  -period: 0
}
alexrsagen commented 5 years ago

@joveice You're passing a new noridEppDomain($request->name) to your noridEppUpdateDomainRequest. You should be passing $domain which you created and set applicant dataset on. You must also use applicant dataset version number 3.0 (see https://www.norid.no/en/registrar/soknad/veiledning/egenerklaring-veiledning/).

joveice commented 5 years ago

@alexrsagen Ah okey, yea I see I have read the unit test wrong (I copied from there since there was no example). Did not know about that, thanks. But I'm going to norid test with fake old data and it has worked. But I'm not the one who gonna be administrating it :D So I tried now with updated code and the fix you did. So I successfully have the datasets now. It still fails tho, it mentions authInfo which I have played around with, this is the error:

 <result code="2001">
      <msg>Command syntax error</msg>
    </result>
    <extension>
      <conditions xmlns="http://www.norid.no/xsd/no-ext-result-1.0" xsi:schemaLocation="http://www.norid.no/xsd/no-ext-result-1.0 no-ext-result-1.0.xsd">
        <condition code="EC000015" severity="error">
          <msg>EPP parse error</msg>
          <details>Parse error at line [2], column [1871]: Element '{urn:ietf:params:xml:ns:domain-1.0}ns': This element is not expected. Expected is ( {urn:ietf:params:xml:ns:domain-1.0}authInfo ).
</details>
        </condition>
      </conditions>
    </extension>

Request:

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xmlns:contact="urn:ietf:params:xml:ns:contact-1.0" xmlns:host="urn:ietf:params:xml:ns:host-1.0" xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1" xmlns:no-ext-epp="http://www.norid.no/xsd/no-ext-epp-1.0" xmlns:no-ext-result="http://www.norid.no/xsd/no-ext-result-1.0" xmlns:no-ext-domain="http://www.norid.no/xsd/no-ext-domain-1.1" xmlns:no-ext-contact="http://www.norid.no/xsd/no-ext-contact-1.0" xmlns:no-ext-host="http://www.norid.no/xsd/no-ext-host-1.0">
  <command>
    <update>
      <domain:update>
        <domain:name>test.no</domain:name>
        <domain:chg>
          <domain:registrant>*removed*</domain:registrant>
          <domain:ns>
            <domain:hostObj>*something*</domain:hostObj>
            <domain:hostObj>*something*</domain:hostObj>
          </domain:ns>
          <domain:contact type="tech">*removed*</domain:contact>
          <domain:authInfo>
            <domain:pw><![CDATA[*removed*]]></domain:pw>
          </domain:authInfo>
        </domain:chg>
      </domain:update>
    </update>
    <extension>
      <no-ext-domain:update>
        <no-ext-domain:chg>
          <no-ext-domain:applicantDataset>
            <no-ext-domain:versionNumber>3.0</no-ext-domain:versionNumber>
            <no-ext-domain:acceptName>*removed*</no-ext-domain:acceptName>
            <no-ext-domain:acceptDate>2012-08-21T12:01:34.00Z</no-ext-domain:acceptDate>
          </no-ext-domain:applicantDataset>
        </no-ext-domain:chg>
      </no-ext-domain:update>
    </extension>
    <clTRID>*removed*</clTRID>
  </command>
</epp>

EDIT: I do not have test.no but I'm removing my info due to company policy rules.

alexrsagen commented 5 years ago

@joveice Please read RFC5731 section 3.2.5 to understand how an EPP domain update request is supposed to work.

Nameserver and contact (other than registrant) updates MUST be performed in <domain:add> or <domain:rem> elements, as specified in the schema definition.

Place your nameserver and technical contact changes in noridEppDomain instances separate from registrant and authInfo changes. Then provide the add, remove and change instances of noridEppDomain to the noridEppUpdateDomainRequest constructor.

Remember to remove any existing technical contacts and nameservers if the intention is to replace the existing set with a new set. This may be done by first performing an info command to get existing contact handles and nameserver hostnames, then performing an update command with the appropriate add and remove elements.

joveice commented 5 years ago

Okey, I have tried a bit now, still a bit much to grab.

So I get failed to update domain. (remove part) Domain [test.no] has no contacts of type [techc] Too few nameservers, minimum is [2] I get accept date in applicant declaration is out of range, guess that is what you mentioned earlier.

How should this look, I'm really confused about the 3 classes so I'm not sure what should contain what.

EDIT: Right, those first errors are probably since I try to remove them and then there are non where there are required. EDIT EDIT: Right, seems like I'm on tracks again, just this date thing

alexrsagen commented 5 years ago

@joveice Unsurprisingly, specifying contacts and nameservers in <domain:add> and <domain:rem> actually does add or remove those contacts and nameservers from the domain, Do not remove all contacts or nameservers unless you intend to replace them with new ones or to actually remove them from the domain. There must always be minimum 1 technical contact and 2 nameservers on a domain according to Norid policy.

Dates must be formatted as ISO 8601 date strings in the UTC(+00) timezone. The reason behind this is:

Example ISO 8601 UTC date: 2019-05-13T10:42:11Z

Please look at the extensive Norid documentation, schema definitions and relevant standards (RFC 5730 - 5734, 5910, W3C Schema) before asking for help next time. These are the sources of truth on this information and as such the quickest methods to get an answer.

joveice commented 5 years ago

Thanks for all the information! I have successfully managed to update the domain and the contacts now, next step is to create and delete which I guess gonna be no issues since I have this bit already working.