File Coverage

blib/lib/AnyEvent/XMPP/Ext/RegisterForm.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package AnyEvent::XMPP::Ext::RegisterForm;
2 1     1   1907 use strict;
  1         4  
  1         41  
3 1     1   50 use AnyEvent::XMPP::Util;
  0            
  0            
4             use AnyEvent::XMPP::Namespaces qw/xmpp_ns/;
5             use AnyEvent::XMPP::Ext::DataForm;
6             use AnyEvent::XMPP::Ext::OOB;
7              
8             =head1 NAME
9              
10             AnyEvent::XMPP::Ext::RegisterForm - Handle for in band registration
11              
12             =head1 SYNOPSIS
13              
14             my $con = AnyEvent::XMPP::Connection->new (...);
15             ...
16             $con->do_in_band_register (sub {
17             my ($form, $error) = @_;
18             if ($error) { print "ERROR: ".$error->string."\n" }
19             else {
20             if ($form->type eq 'simple') {
21             if ($form->has_field ('username') && $form->has_field ('password')) {
22             $form->set_field (
23             username => 'test',
24             password => 'qwerty',
25             );
26             $form->submit (sub {
27             my ($form, $error) = @_;
28             if ($error) { print "SUBMIT ERROR: ".$error->string."\n" }
29             else {
30             print "Successfully registered as ".$form->field ('username')."\n"
31             }
32             });
33             } else {
34             print "Couldn't fill out the form: " . $form->field ('instructions') ."\n";
35             }
36             } elsif ($form->type eq 'data_form' {
37             my $dform = $form->data_form;
38             ... fill out the form $dform (of type AnyEvent::XMPP::DataForm) ...
39             $form->submit_data_form ($dform, sub {
40             my ($form, $error) = @_;
41             if ($error) { print "DATA FORM SUBMIT ERROR: ".$error->string."\n" }
42             else {
43             print "Successfully registered as ".$form->field ('username')."\n"
44             }
45             })
46             }
47             }
48             });
49              
50             =head1 DESCRIPTION
51              
52             This module represents an in band registration form
53             which can be filled out and submitted.
54              
55             You can get an instance of this class only by requesting it
56             from a L by calling the C
57             method.
58              
59             =over 4
60              
61             =item B
62              
63             Usually the constructor takes no arguments except when you want to construct
64             an answer form, then you call the constructor like this:
65              
66             If you have legacy form fields as a hash ref in C<$filled_legacy_form>:
67              
68             AnyEvent::XMPP::Ext::RegisterForm (
69             legacy_form => $filled_legacy_form,
70             answered => 1
71             );
72              
73             If you have a data form in C<$answer_data_form>:
74              
75             AnyEvent::XMPP::Ext::RegisterForm (
76             legacy_form => $answer_data_form,
77             answered => 1
78             );
79              
80             =cut
81              
82             sub new {
83             my $this = shift;
84             my $class = ref($this) || $this;
85             my $self = bless { @_ }, $class;
86             $self
87             }
88              
89             =item B
90              
91             This method tries to fill out a form which was received from the
92             other end. It enters the username and password and returns a
93             new L object which is the answer
94             form.
95              
96             B This function is just a heuristic to fill out a form for automatic
97             registration, but it might fail if the forms are more complex and have
98             required fields that we don't know.
99              
100             Registration without user interaction is theoretically not possible because
101             forms can be different from server to server and require different information.
102             Please also have a look at XEP-0077.
103              
104             Note that if the form is more complicated this method will not work
105             and it's not guranteed that the registration will be successful.
106              
107             Calling this method on a answer form (where C returns true)
108             will have an undefined result.
109              
110             =cut
111              
112             sub try_fillout_registration {
113             my ($self, $username, $password) = @_;
114              
115             my $form;
116             my $nform;
117              
118             if (my $df = $self->get_data_form) {
119             my $af = AnyEvent::XMPP::Ext::DataForm->new;
120             $af->make_answer_form ($df);
121             $af->set_field_value (username => $username);
122             $af->set_field_value (password => $password);
123             $nform = $af;
124              
125             } else {
126             $form = {
127             username => $username,
128             password => $password
129             };
130             }
131              
132             return
133             AnyEvent::XMPP::Ext::RegisterForm->new (
134             data_form => $nform,
135             legacy_form => $form,
136             answered => 1
137             );
138             }
139              
140             =item B
141              
142             This method will return a true value if this form was returned by eg.
143             C or generally represents an answer form.
144              
145             =cut
146              
147             sub is_answer_form {
148             my ($self) = @_;
149             $self->{answered}
150             }
151              
152             =item B
153              
154             This method returns true if the received form
155             were just the current registration data. Basically this method returns
156             true when you are already registered to the server.
157              
158             =cut
159              
160             sub is_already_registered {
161             my ($self) = @_;
162             exists $self->{legacy_form}
163             && exists $self->{legacy_form}->{registered}
164             }
165              
166             =item B
167              
168             This method returns a hash with the keys being the fields
169             of the legacy form as described in the XML scheme of XEP-0077.
170              
171             If the form contained just nodes the keys will have undef as value.
172              
173             If the form contained also register information, in case C
174             returns a true value, the values will contain the strings for the fields.
175              
176             =cut
177              
178             sub get_legacy_form_fields {
179             my ($self) = @_;
180             $self->{legacy_form}
181             }
182              
183             =item B
184              
185             This method returns the L that came
186             with the registration response. If no data form was provided by the
187             server this method returns undef.
188              
189             =cut
190              
191             sub get_data_form {
192             my ($self) = @_;
193             $self->{data_form}
194             }
195              
196              
197             =item B
198              
199             This method returns a hash like the one returned from
200             the function C in L.
201             It contains the out of band data for this registration form.
202              
203             =cut
204              
205             sub get_oob {
206             my ($self) = @_;
207             $self->{oob}
208             }
209              
210             sub init_new_form {
211             my ($self, $formnode) = @_;
212              
213             my $df = AnyEvent::XMPP::Ext::DataForm->new;
214             $df->from_node ($formnode);
215             $self->{data_form} = $df;
216             }
217              
218             sub _get_legacy_form {
219             my ($self, $node) = @_;
220              
221             my $form = {};
222              
223             my ($qnode) = $node->find_all ([qw/register query/]);
224              
225             return $form unless $qnode;
226              
227             for ($qnode->nodes) {
228             if ($_->eq_ns ('register')) {
229             $form->{$_->name} = $_->text;
230             }
231             }
232              
233             $form
234             }
235              
236             sub init_from_node {
237             my ($self, $node) = @_;
238              
239             if (my (@form) = $node->find_all ([qw/register query/], [qw/data_form x/])) {
240             $self->init_new_form (@form);
241             }
242             if (my ($xoob) = $node->find_all ([qw/register query/], [qw/x_oob x/])) {
243             $self->{oob} = AnyEvent::XMPP::Ext::OOB::url_from_node ($xoob);
244             }
245             $self->{legacy_form} = $self->_get_legacy_form ($node);
246             }
247              
248             =item B
249              
250             This method returns a list of C nodes.
251              
252             =cut
253              
254             sub answer_form_to_simxml {
255             my ($self) = @_;
256              
257             if ($self->{data_form}) {
258             my $sxl = $self->{data_form}->to_simxml;
259             return $sxl;
260              
261             } else {
262             my @childs;
263              
264             my $lf = $self->get_legacy_form_fields;
265              
266             for (keys %$lf) {
267             push @childs, {
268             ns => 'register',
269             dns => 'register',
270             name => $_,
271             childs => [ $lf->{$_} ]
272             }
273             }
274              
275             return @childs;
276             }
277             }
278              
279             =back
280              
281             =head1 AUTHOR
282              
283             Robin Redeker, C<< >>, JID: C<< >>
284              
285             =head1 COPYRIGHT & LICENSE
286              
287             Copyright 2007, 2008 Robin Redeker, all rights reserved.
288              
289             This program is free software; you can redistribute it and/or modify it
290             under the same terms as Perl itself.
291              
292             =cut
293              
294             1; # End of AnyEvent::XMPP::RegisterForm