File Coverage

blib/lib/XML/EPP.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1              
2             package XML::EPP;
3              
4 6     6   252288 use Moose;
  0            
  0            
5             use MooseX::Method::Signatures;
6             use Moose::Util::TypeConstraints;
7             use MooseX::StrictConstructor;
8              
9             use constant XSI_XMLNS => "http://www.w3.org/2001/XMLSchema-instance";
10              
11             use XML::EPP::Common;
12              
13             our $VERSION = "0.05_02";
14              
15             our $PKG;
16             BEGIN{ $PKG = "XML::EPP" };
17              
18             #=====================================================================
19             # epp-1.0.xsd mapping to types
20             #=====================================================================
21             # as this module describes the message format (ie, epp-1.0.xsd), it
22             # contains all of the types from that namespace, as well as the
23             # definition of the node.
24              
25             # in principle, this should be generated programmatically; however
26             # this is a manual conversion based on a set of principles which are
27             # outlined in the comments.
28              
29             # rule 1. simpleTypes become subtypes of basic types. We need an
30             # XMLSchema type library for the 'built-in' XMLSchema types, I'll put
31             # them for the time being in:
32             use PRANG::XMLSchema::Types;
33              
34             BEGIN {
35             subtype "${PKG}::sIDType"
36             => as "PRANG::XMLSchema::normalizedString"
37             => where {
38             length($_) >= 3 and length($_) <= 64;
39             };
40              
41             subtype "${PKG}::versionType"
42             => as "PRANG::XMLSchema::token"
43             => where {
44             m{^[1-9]+\.[0-9]+$} and $_ eq "1.0";
45             };
46              
47             subtype "${PKG}::trIDStringType"
48             => as "PRANG::XMLSchema::token"
49             => where {
50             length($_) >= 3 and length($_) <= 64;
51             };
52              
53             subtype "${PKG}::pwType"
54             => as "PRANG::XMLSchema::token"
55             => where {
56             length($_) >= 6 and length($_) <= 16;
57             };
58             }
59              
60             # rule 2. ALL elements get converted to MessageNode types, with
61             # classes preferably named after the name of the element
62             use XML::EPP::Hello;
63              
64             # however, as 'extURIType' is used in multiple places, with different
65             # element names, it gets a name based on its type.
66             use XML::EPP::ExtURI;
67             use XML::EPP::SvcMenu;
68             use XML::EPP::DCP;
69             use XML::EPP::Greeting;
70             use XML::EPP::CredsOptions;
71             use XML::EPP::RequestedSvcs;
72             use XML::EPP::Login;
73             use XML::EPP::Poll;
74             use XML::EPP::SubCommand;
75             use XML::EPP::Transfer;
76              
77             # first rule: map complexTypes to classes. Where types are only used
78             # in one place, the name of the class is the name of the *element* in
79             # which it is used.
80             use XML::EPP::Command;
81             use XML::EPP::TrID;
82             use XML::EPP::Extension;
83             use XML::EPP::Msg;
84             use XML::EPP::Result;
85             use XML::EPP::Response;
86              
87             #=====================================================================
88             # 'epp' node definition
89             #=====================================================================
90             use PRANG::Graph;
91              
92             # Now we have all of the type constraints from the XMLSchema
93             # definition defined, we can implement the 'epp' node.
94              
95             # there is a 'choice' - this item has no name in the schema to use, so
96             # we call it 'choice0'
97             subtype "${PKG}::choice0" =>
98             => as join("|", map { "${PKG}::$_" }
99             qw(greetingType Hello commandType
100             responseType extAnyType) );
101              
102             # but we map it to the object property 'message'; again this comes
103             # under 'schema customisation'
104             has_element 'message' =>
105             is => "rw",
106             isa => "${PKG}::choice0",
107             required => 1,
108             xml_nodeName => {
109             "greeting" => "${PKG}::Greeting",
110             "command" => "${PKG}::Command",
111             "response" => "${PKG}::Response",
112             "extension" => "${PKG}::Extension",
113             "hello" => "${PKG}::Hello",
114             },
115             handles => ["is_response"],
116             ;
117              
118             method root_element { "epp" }
119              
120             # this class implements a Message format - ie, a root of a schema - as
121             # well as a node - the documentRoot
122             with "PRANG::Graph", "XML::EPP::Node";
123              
124             method is_command() {
125             $self->message->is_command;
126             }
127              
128             method is_response() {
129             !$self->message->is_command;
130             }
131              
132             sub _reg {
133             shift if eval { $_[0]->isa(__PACKAGE__) };
134             my $hash = shift;
135             my $uri = shift;
136             my $pkg_space = shift || 1;
137             $hash->{$uri} = $pkg_space;
138             }
139             our @epp_versions = "1.0";
140             our @epp_lang = "en";
141             our %obj_uris;
142             our %ext_uris;
143             sub register_obj_uri {
144             }
145              
146             sub register_ext_uri {
147             }
148              
149             1;
150              
151             =head1 NAME
152              
153             XML::EPP - an implementation of the EPP XML language
154              
155             =head1 SYNOPSIS
156              
157             use XML::EPP;
158              
159             my $foo_create = XML::EPP->new(
160             message => XML::EPP::Command->new(
161             action => "create",
162             argument => XML::EPP::SubCommand->new(
163             payload => XML::EPP::Obj::create->new(
164             ...
165             ),
166             ),
167             clTRID => "xml_epp_".time."_$$",
168             ),
169             );
170              
171             print $foo_create->to_xml;
172              
173             =head1 DESCRIPTION
174              
175             This module is an implementation of the XML protocol used by most
176             major domain registries around the world. This protocol was developed
177             between 2002 and 2004, using XML standards which were at the time very
178             new, such as XML Namespaces and XML Schema. It saw several
179             incompatible revisions until the 1.0 version which became RFC3730.
180              
181             This module hopes to create a Free Software, complete, user-friendly
182             and standards compliant interface to both client and server sides of
183             the EPP specification.
184              
185             =head2 WARNING: SITE^WMODULE UNDER CONSTRUCTION
186              
187             The classes which are present, while enough to be able to parse the
188             RFC, are not fixed in API terms until they are documented and tested.
189             Please consider any attribute which is not yet at least documented to
190             be under review and subject to rename. This is thought to lead to a
191             clearer implementation than fixing attribute names to the somewhat
192             random (though well-known) names used in the EPP XML. Use of C<sub
193             BUILDARGS { }> to allow either may be considered; patches welcome.
194              
195             Similarly with undocumented portions of the implementation. If you
196             would like to make sure that the code you write against it doesn't
197             need rewriting, please send a patch/pull request!
198              
199             This module currently implements the XML part of the protocol only;
200             converting this into an actual EPP session is currently TO-DO. Also,
201             none of the mappings for essential registry types, such as domain,
202             contact or host are yet implemented. This is a preview release.
203              
204             =head1 PARSING AN EPP MESSAGE
205              
206             This part currently works very well. Feed in some valid XML
207             I<thusly>;
208              
209             use XML::EPP;
210             my $message = XML::EPP->parse( $xml );
211              
212             If you can find B<any> RFC5730-valid document (including RFC5731,
213             RFC5732 or RFC5733) this doesn't parse, then you win a bag of
214             chocolate fish. Similarly if you find an RFC-invalid document that
215             this module accepts blindly. Please log an RT ticket and contact the
216             author privately for delivery of the chocolate.
217              
218             =head1 CREATING AN EPP MESSAGE
219              
220             There is an example in the C<SYNOPSIS>, but essentially the regular
221             Moose constructor is all that is provided in this module.
222              
223             =head2 HINTS
224              
225             Look out for convenience construction interfaces. These are primarily
226             useful C<coerce> rules (see L<Moose::Util::TypeConstraints>).
227              
228             For example, instead of writing (in the middle of constructing a
229             L<XML::EPP::DCP> stack):
230              
231             recipient => XML::EPP::DCP::Recipient->new(
232             same => 1,
233             ours => [
234             XML::EPP::DCP::Ours->new( name => "SomeCo Ltd" ),
235             XML::EPP::DCP::Ours->new( name => "Partner Ltd" ),
236             ],
237             ),
238              
239             Coerce rules are defined to make this work:
240              
241             recipient => [ qw(same), "SomeCo Ltd", "Partner Ltd" ];
242              
243             Both construct the same stack of objects, and would serialize to:
244              
245             <recipient xmlns="urn:ietf:params:xml:ns:epp-1.0">
246             <ours><recDesc>SomeCo Ltd</recDesc></ours>
247             <ours><recDesc>Parnet Ltd</recDesc></ours>
248             <same/>
249             </recipient>
250              
251             For this to be most useful, the rules are hand-written for each class.
252              
253             =head1 GLOBALS / CLASS METHODS
254              
255             =head2 C<@XML::EPP::epp_versions>
256              
257             The list of EPP versions implemented by this module. Default value is
258             C<("1.0", )>.
259              
260             =head2 C<@XML::EPP::epp_lang>
261              
262             The list of EPP languages implemented by this module. Default value
263             is C<("en", )>.
264              
265             =head2 register_obj_uri( $uri[, $namespace])
266              
267             Register the namespace C<$namespace> as corresponding to the C<$uri>
268             URI. Object types such as L<XML::EPP::Domain>, etc will use this to
269             register themselves. The loaded object types are available in the
270             global variable C<@XML::EPP::obj_uris>
271              
272             =head2 register_ext_uri( $uri[, $namespace])
273              
274             Exactly the same as the above, but the URI will be advertised as an
275             extension, not an object type.
276              
277             =head1 SOURCE, SUBMISSIONS, SUPPORT
278              
279             Source code is available from Catalyst:
280              
281             git://git.catalyst.net.nz/XML-EPP.git
282              
283             And Github:
284              
285             git://github.com/catalyst/XML-EPP.git
286              
287             Please see the file F<SubmittingPatches> for information on preferred
288             submission formats.
289              
290             Suggested avenues for support:
291              
292             =over
293              
294             =item *
295              
296             The DNRS forum on SourceForge -
297             L<http://sourceforge.net/projects/dnrs/forums>
298              
299             =item *
300              
301             Contact the author and ask either politely or commercially for help.
302              
303             =item *
304              
305             Log a ticket on L<http://rt.cpan.org/>
306              
307             =back
308              
309             =head1 SEE ALSO
310              
311             L<XML::EPP::Changes> for what has most recently been added to
312             L<XML::EPP>.
313              
314             L<XML::EPP::Domain> - an implementation of the RFC5731 domain mapping
315              
316             L<XML::EPP::Host> - an implementation of the RFC5732 host mapping
317              
318             L<XML::EPP::Contact> - an implementation of the RFC5733 contact
319             mapping
320              
321             =head1 AUTHOR AND LICENCE
322              
323             Development commissioned by NZ Registry Services, and carried out by
324             Catalyst IT - L<http://www.catalyst.net.nz/>
325              
326             Copyright 2009, 2010, NZ Registry Services. This module is licensed
327             under the Artistic License v2.0, which permits relicensing under other
328             Free Software licenses.
329              
330             =cut
331