File Coverage

blib/lib/WebService/iThenticate/Request.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package WebService::iThenticate::Request;
2              
3 1     1   33357 use strict;
  1         2  
  1         40  
4 1     1   6 use warnings;
  1         1  
  1         35  
5              
6 1     1   482 use RPC::XML;
  0            
  0            
7              
8             $RPC::XML::ENCODING = 'UTF-8';
9              
10             our $VERSION = 0.16;
11              
12             =head1 NAME
13              
14             WebService::iThenticate::Request - create request objects for the WebService::iThenticate
15              
16             =head1 SYNOPSIS
17              
18             # construct a new API request
19             $request = WebService::iThenticate::Request->new( {
20             method => 'login', # required
21             auth => $auth_object, # auth object appropriate to the transport mechanism
22             } );
23              
24             # make the request using an WebService::iThenticate::Client user agent
25             $response = $client->make_request( { request => $request } );
26              
27             # dump out the request as a string
28             $string = $request->as_string;
29              
30              
31             =head1 DESCRIPTION
32              
33              
34             =head1 VARIABLES
35              
36             =over 4
37              
38             =item Validations
39              
40             This package scoped hash consists of methods and their required
41             arguments. It is necessary because we cannot always rely on the server
42             to validate request arguments.
43              
44             =back
45              
46             =cut
47              
48             # we use a simple hash for validation here instead of Params::Validate
49             # just to keep the dependencies to a minimum.
50              
51             # had to no critic this next line; why are we not allowing package variables?
52             our %Validations = ( ## no critic
53             'document.get' => { id => 'int' },
54             'document.trash' => { id => 'int' },
55              
56             'report.get' => { id => 'int' },
57              
58             'user.add' => {
59             first_name => 'string',
60             last_name => 'string',
61             email => 'string', },
62              
63             'user.drop' => { id => 'int' },
64              
65             'group.add' => { name => 'string' },
66             'group.folders' => { id => 'int' },
67             'group.drop' => { id => 'int' },
68              
69             'folder.add' => {
70             name => 'string',
71             description => 'string',
72             folder_group => 'int',
73             exclude_quotes => 'boolean', }, # add_to_index is optional
74              
75             'folder.get' => { id => 'int' },
76             'folder.trash' => { id => 'int' },
77             );
78              
79              
80              
81             =head1 METHODS
82              
83             =over 4
84              
85             =item new()
86              
87             # construct a new API request
88             $request = WebService::iThenticate::Request->new({
89             method => 'login', # required
90             auth => $auth_object, # required
91             });
92              
93             =cut
94              
95             sub new {
96             my ( $class, $args ) = @_;
97              
98             my $method = $args->{method} || die 'no method passed';
99             my $auth = $args->{auth} || die 'no auth passed';
100             my $novalidate = delete $args->{novalidate} || undef;
101              
102             # create a data structure for the rpc struct
103             my %struct_args = %{$auth};
104              
105             # handle the novalidate workaround needed for document.add method
106             my $validated_args;
107             if ( !$novalidate ) {
108              
109             # arguments specific to the request were passed so validate them
110             $validated_args = eval { $class->validate( $method, $args->{req_args} ) };
111             die "parameter validation failed: $@\n" if $@;
112             } elsif ( $novalidate && $args->{req_args} ) {
113              
114             $validated_args = $args->{req_args};
115             }
116              
117             if ( $validated_args ) {
118             foreach my $arg_key ( keys %{$validated_args} ) {
119             $struct_args{$arg_key} = $validated_args->{$arg_key};
120             }
121             }
122              
123             my $rpc_request = RPC::XML::request->new(
124             $args->{method}, RPC::XML::struct->new( \%struct_args ),
125             );
126             die 'could not create new rpc request object' unless $rpc_request;
127              
128             # validation complete, create the object
129             my %self;
130             bless \%self, $class;
131              
132             $self{rpc_request} = $rpc_request;
133              
134             return \%self;
135              
136             } ## end sub new
137              
138             =item validate()
139              
140             my $validated_args = eval { $class->validate( $method, $args->{req_args} ) };
141              
142             Given an xmlrpc method, and a hash reference of key value argument pairs,
143             this returns the corresponding RPC::XML entities. If any arguments are
144             missing or invalid, this method dies with an appropriate error string;
145              
146             =cut
147              
148              
149             sub validate {
150             my ( $class, $method, $args ) = @_;
151              
152             return $args unless exists $Validations{$method};
153              
154             my $validate = $Validations{$method};
155             my %validated;
156              
157             # check to make sure the required arguments are of the right type
158             foreach my $key ( keys %{$validate} ) {
159             die "required arg $key not present\n" unless defined $args->{$key};
160             my $sub = '_' . $validate->{$key};
161              
162             # validate the argument
163             no strict 'refs'; ## no critic
164             $validated{$key} = $sub->( $key, delete $args->{$key} );
165             }
166              
167             # add optional arguments that don't require validation
168             $validated{$_} = $args->{$_} for keys %{$args};
169              
170             return \%validated;
171             } ## end sub validate
172              
173             sub _int {
174             my ( $key, $val ) = @_;
175              
176             # our friendly RPC::XML library doesn't actually verify this is an
177             # integer so we have to run an additional check
178             die "$key value $val is not an integer\n" unless $val =~ m/^\d+$/;
179              
180             return RPC::XML::int->new( $val );
181             }
182              
183             sub _boolean {
184             my ( $key, $val ) = @_;
185              
186             # RPC::XML is broken for booleans also :(
187             die "$key is not a boolean\n" unless $val =~ m/^(?:0|1|yes|no|true|false)$/;
188              
189             return RPC::XML::boolean->new( $val );
190             }
191              
192             sub _string {
193             my ( $key, $val ) = @_;
194              
195             return RPC::XML::string->new( $val );
196             }
197              
198              
199             =back
200              
201             =head1 FAQ
202              
203             Q: Why are you using this hodge podge validation scheme instead of
204             Params::Validate?
205              
206             A: To minimize the number of dependencies. Partly evil yes, but easy
207             install is one of the goals of this module.
208              
209             =head1 BUGS
210              
211             Plenty at this stage I'm sure. Send patches to the author.
212              
213             =head1 SEE ALSO
214              
215             WebService::iThenticate::Client, WebService::iThenticate::Response, RPC::XML
216              
217             =head1 AUTHOR
218              
219             Fred Moyer
220              
221             =head1 COPYRIGHT
222              
223             Copyright (C) (2012) iParadigms, LLC. All rights reserved.
224              
225             =head1 LICENSE
226              
227             This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available.
228              
229              
230             =cut
231              
232              
233             1;