File Coverage

blib/lib/AnyEvent/XMPP/Ext/Registration.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::Registration;
2 1     1   1526 use strict;
  1         3  
  1         26  
3 1     1   32 use AnyEvent::XMPP::Util;
  0            
  0            
4             use AnyEvent::XMPP::Namespaces qw/xmpp_ns/;
5             use AnyEvent::XMPP::Ext::RegisterForm;
6              
7             =head1 NAME
8              
9             AnyEvent::XMPP::Ext::Registration - Handles all tasks of in band registration
10              
11             =head1 SYNOPSIS
12              
13             my $con = AnyEvent::XMPP::Connection->new (...);
14              
15             $con->reg_cb (stream_pre_authentication => sub {
16             my ($con) = @_;
17             my $reg = AnyEvent::XMPP::Ext::Registration->new (connection => $con);
18              
19             $reg->send_registration_request (sub {
20             my ($reg, $form, $error) = @_;
21              
22             if ($error) {
23             # error handling
24              
25             } else {
26             my $af = $form->try_fillout_registration ("tester", "secret");
27              
28             $reg->submit_form ($af, sub {
29             my ($reg, $ok, $error, $form) = @_;
30              
31             if ($ok) { # registered successfully!
32             $con->authenticate
33              
34             } else { # error
35             if ($form) { # we got an alternative form!
36             # fill it out and submit it with C again
37             }
38             }
39             });
40             }
41             });
42              
43             0
44             });
45              
46             =head1 DESCRIPTION
47              
48             This module handles all tasks of in band registration that are possible and
49             specified by XEP-0077. It's mainly a helper class that eases some tasks such
50             as submitting and retrieving a form.
51              
52             =cut
53              
54             =head1 METHODS
55              
56             =over 4
57              
58             =item B
59              
60             This is the constructor for a registration object.
61              
62             =over 4
63              
64             =item connection
65              
66             This must be a L (or some other subclass of that) object.
67              
68             This argument is required.
69              
70             =back
71              
72             =cut
73              
74             sub new {
75             my $this = shift;
76             my $class = ref($this) || $this;
77             my $self = bless { @_ }, $class;
78             $self->init;
79             $self
80             }
81              
82             sub init {
83             my ($self) = @_;
84             #...
85             }
86              
87             =item B
88              
89             This method sends a register form request.
90             C<$cb> will be called when either the form arrived or
91             an error occured.
92              
93             The first argument of C<$cb> is always C<$self>.
94             If the form arrived the second argument of C<$cb> will be
95             a L object.
96             If an error occured the second argument will be undef
97             and the third argument will be a L
98             object.
99              
100             For hints how L should be filled
101             out look in XEP-0077. Either you have legacy form fields, out of band
102             data or a data form.
103              
104             See also L in L.
105              
106             =cut
107              
108             sub send_registration_request {
109             my ($self, $cb) = @_;
110              
111             my $con = $self->{connection};
112              
113             $con->send_iq (get => {
114             defns => 'register',
115             node => { ns => 'register', name => 'query' }
116             }, sub {
117             my ($node, $error) = @_;
118              
119             my $form;
120             if ($node) {
121             $form = AnyEvent::XMPP::Ext::RegisterForm->new;
122             $form->init_from_node ($node);
123             } else {
124             $error =
125             AnyEvent::XMPP::Error::Register->new (
126             node => $error->xml_node, register_state => 'register'
127             );
128             }
129              
130             $cb->($self, $form, $error);
131             });
132             }
133              
134             sub _error_or_form_cb {
135             my ($self, $e, $cb) = @_;
136              
137             $e = $e->xml_node;
138              
139             my $error =
140             AnyEvent::XMPP::Error::Register->new (
141             node => $e, register_state => 'submit'
142             );
143              
144             if ($e->find_all ([qw/register query/], [qw/data_form x/])) {
145             my $form = AnyEvent::XMPP::Ext::RegisterForm->new;
146             $form->init_from_node ($e);
147              
148             $cb->($self, 0, $error, $form)
149             } else {
150             $cb->($self, 0, $error, undef)
151             }
152             }
153              
154             =item B
155              
156             This method sends an unregistration request.
157              
158             For description of the semantics of the callback in C<$cb>
159             plase look in the description of the C method below.
160              
161             =cut
162              
163             sub send_unregistration_request {
164             my ($self, $cb) = @_;
165              
166             my $con = $self->{connection};
167              
168             $con->send_iq (set => {
169             defns => 'register',
170             node => { ns => 'register', name => 'query', childs => [
171             { ns => 'register', name => 'remove' }
172             ]}
173             }, sub {
174             my ($node, $error) = @_;
175             if ($node) {
176             $cb->($self, 1)
177             } else {
178             $self->_error_or_form_cb ($error, $cb);
179             }
180             });
181             }
182              
183             =item B
184              
185             This method sends a password change request for the user C<$username>
186             with the new password C<$password>.
187              
188             For description of the semantics of the callback in C<$cb>
189             plase look in the description of the C method below.
190              
191             =cut
192              
193             sub send_password_change_request {
194             my ($self, $username, $password, $cb) = @_;
195              
196             my $con = $self->{connection};
197              
198             $con->send_iq (set => {
199             defns => 'register',
200             node => { ns => 'register', name => 'query', childs => [
201             { ns => 'register', name => 'username', childs => [ $username ] },
202             { ns => 'register', name => 'password', childs => [ $password ] },
203             ]}
204             }, sub {
205             my ($node, $error) = @_;
206             if ($node) {
207             $cb->($self, 1, undef, undef)
208             } else {
209             $self->_error_or_form_cb ($error, $cb);
210             }
211             });
212             }
213              
214             =item B
215              
216             This method submits the C<$form> which should be of
217             type L and should be an answer
218             form.
219              
220             C<$con> is the connection on which to send this form.
221              
222             C<$cb> is the callback that will be called once the form has been submitted and
223             either an error or success was received. The first argument to the callback
224             will be the L object, the second will be a
225             boolean value that is true when the form was successfully transmitted and
226             everything is fine. If the second argument is false then the third argument is
227             a L object. If the error contained a data form
228             which is required to successfully make the request then the fourth argument
229             will be a L which you should fill out and send
230             again with C.
231              
232             For the semantics of such an error form see also XEP-0077.
233              
234             =cut
235              
236             sub submit_form {
237             my ($self, $form, $cb) = @_;
238              
239             my $con = $self->{connection};
240              
241             $con->send_iq (set => {
242             defns => 'register',
243             node => { ns => 'register', name => 'query', childs => [
244             $form->answer_form_to_simxml
245             ]}
246             }, sub {
247             my ($n, $e) = @_;
248              
249             if ($n) {
250             $cb->($self, 1, undef, undef)
251             } else {
252             $self->_error_or_form_cb ($e, $cb);
253             }
254             });
255             }
256              
257             =back
258              
259             =head1 AUTHOR
260              
261             Robin Redeker, C<< >>, JID: C<< >>
262              
263             =head1 COPYRIGHT & LICENSE
264              
265             Copyright 2007, 2008 Robin Redeker, all rights reserved.
266              
267             This program is free software; you can redistribute it and/or modify it
268             under the same terms as Perl itself.
269              
270             =cut
271              
272             1; # End of AnyEvent::XMPP::Ext::Registration