File Coverage

lib/XML/Compile/SOAP/WSS.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             # Copyrights 2011-2014 by [Mark Overmeer].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.01.
5 1     1   2069 use warnings;
  1         3  
  1         38  
6 1     1   5 use strict;
  1         2  
  1         65  
7              
8             package XML::Compile::SOAP::WSS;
9             our $VERSION = '1.12';
10              
11 1     1   5 use base 'XML::Compile::SOAP::Extension';
  1         2  
  1         813  
12              
13             use Log::Report 'xml-compile-wss';
14              
15             use XML::Compile::WSS::Util qw/:wss11 :utp11/;
16             use XML::Compile::WSS ();
17             use XML::Compile::SOAP::Util qw/SOAP11ENV/;
18              
19             use Scalar::Util qw/weaken/;
20              
21              
22             sub init($)
23             { my ($self, $args) = @_;
24             $self->SUPER::init($args);
25             $self->{XCSW_wss} = [];
26              
27             my $schema = $self->{XCSW_schema} = $args->{schema};
28             weaken $self->{XCSW_schema};
29              
30             # [1.0] to support backwards compat
31             XML::Compile::WSS->loadSchemas($schema, '1.1') if $schema;
32             $self;
33             }
34              
35             sub wsdl11Init($$)
36             { my ($self, $wsdl, $args) = @_;
37             $self->SUPER::wsdl11Init($wsdl, $args);
38              
39             $self->{XCSW_schema} = $wsdl;
40             weaken $self->{XCSW_schema};
41              
42             XML::Compile::WSS->loadSchemas($wsdl, '1.1');
43             $wsdl->addPrefixes('SOAP-ENV' => SOAP11ENV);
44              
45             $self;
46             }
47              
48             sub soap11OperationInit($$)
49             { my ($self, $op, $args) = @_;
50              
51             my $schema = $self->schema
52             or error __x"WSS not connected to the WSDL: WSS needs to be instantiated
53             before the WSDL because it influences its interpretation";
54              
55             trace "adding wss header logic"; # get full type from any schema
56             my $sec = $schema->findName('wsse:Security');
57             $op->addHeader(INPUT => "wsse_Security" => $sec, mustUnderstand => 1);
58             $op->addHeader(OUTPUT => "wsse_Security" => $sec, mustUnderstand => 1);
59             }
60             *soap12OperationInit = \&soap11OperationInit;
61              
62             sub soap11ClientWrapper($$$)
63             { my ($self, $op, $call, $args) = @_;
64             sub {
65             my $data = @_==1 ? shift : {@_};
66             my $sec = $data->{wsse_Security};
67              
68             # Support pre-1.0 interface
69             return $call->($data)
70             if ref $sec eq 'HASH';
71              
72             # select plugins
73             my $wss = $sec || $self->{XCSW_wss};
74             my @wss = ref $wss eq 'ARRAY' ? @$wss : $wss;
75              
76             # Adding WSS headers to $secw
77             my $secw = $data->{wsse_Security} = {};
78             my $doc = $data->{_doc} ||= XML::LibXML::Document->new('1.0','UTF-8');
79             $_->create($doc, $secw) for @wss;
80            
81             # The real work: SOAP message formatting and exchange
82             my ($answer, $trace) = $call->($data);
83              
84             if(defined $answer)
85             { my $secr = $answer->{wsse_Security} ||= {};
86             $_->check($secr) for @wss;
87             }
88            
89             wantarray ? ($answer, $trace) : $answer;
90             };
91             }
92             *soap12ClientWrapper = \&soap11ClientWrapper;
93              
94             #---------------------------
95              
96             sub schema() { shift->{XCSW_schema} }
97             sub features() { @{shift->{XCSW_wss}} }
98              
99             sub addFeature($)
100             { my ($self, $n) = @_;
101             my $schema = $n->schema
102             or error __x"no schema yet. Instantiate ::WSS before ::WSDL";
103              
104             push @{$self->{XCSW_wss}}, $n;
105             $n;
106             }
107              
108             #---------------------------
109              
110             sub _start($$)
111             { my ($self, $plugin, $args) = @_;
112              
113             eval "require $plugin";
114             panic $@ if $@;
115              
116             my $schema = $args->{schema} ||= $self->schema
117             or error __x"instantiate {pkg} before the wsdl, plugins after"
118             , pkg => __PACKAGE__;
119              
120             $self->addFeature($plugin->new($args));
121             }
122              
123              
124             sub basicAuth(%)
125             { my ($self, %args) = @_;
126             $self->_start('XML::Compile::WSS::BasicAuth', \%args);
127             }
128              
129              
130             sub timestamp(%)
131             { my ($self, %args) = @_;
132             $self->_start('XML::Compile::WSS::Timestamp', \%args);
133             }
134              
135              
136             sub signature(%)
137             { my ($self, %args) = @_;
138             my $schema = $args{schema} || $self->schema;
139              
140             my $has12 = defined $schema->prefix('env12');
141             $args{sign_types} ||= ['SOAP-ENV:Body', ($has12 ? 'env12:Body' : ())];
142             $args{sign_put} ||= 'wsse:SecurityHeaderType';
143             $args{sign_when} ||= ['SOAP-ENV:Envelope', ($has12 ? 'env12:Envelope':())];
144              
145             my $sig = $self->_start('XML::Compile::WSS::Signature', \%args);
146             $sig;
147             }
148              
149             #--------------------------------------
150             # [1.0] Expired interface
151             sub wsseBasicAuth($$$@)
152             { my ($self, $username, $password, $pwtype, %args) = @_;
153             # use XML::Compile::WSS::BasicAuth!!! This method will be removed!
154              
155             eval "require XML::Compile::WSS::BasicAuth";
156             panic $@ if $@;
157              
158             my $auth = XML::Compile::WSS::BasicAuth->new
159             ( username => $username
160             , password => $password
161             , pwformat => $pwtype || UTP11_PTEXT
162             , %args
163             , schema => $self->schema
164             );
165              
166             my $doc = XML::LibXML::Document->new('1.0', 'UTF-8');
167             $auth->create($doc, {});
168             }
169              
170             # [1.0] Expired interface
171             sub wsseTimestamp($$$@)
172             { my ($self, $created, $expires, %args) = @_;
173             # use XML::Compile::WSS::Timestamp!!! This method will be removed!
174              
175             eval "require XML::Compile::WSS::Timestamp";
176             panic $@ if $@;
177              
178             my $ts = XML::Compile::WSS::Timestamp->new
179             ( created => $created
180             , expires => $expires
181             , %args
182             , schema => $self->schema
183             );
184              
185             my $doc = XML::LibXML::Document->new('1.0', 'UTF-8');
186             $ts->create($doc, {});
187             }
188              
189             1;