File Coverage

lib/XML/Compile/WSS/BasicAuth.pm
Criterion Covered Total %
statement 30 91 32.9
branch 0 20 0.0
condition 0 14 0.0
subroutine 10 25 40.0
pod 7 9 77.7
total 47 159 29.5


line stmt bran cond sub pod time code
1             # Copyrights 2011-2015 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   1423 use warnings;
  1         2  
  1         47  
6 1     1   5 use strict;
  1         2  
  1         39  
7              
8             package XML::Compile::WSS::BasicAuth;
9 1     1   7 use vars '$VERSION';
  1         1  
  1         76  
10             $VERSION = '1.13';
11              
12 1     1   6 use base 'XML::Compile::WSS';
  1         2  
  1         128  
13              
14 1     1   7 use Log::Report 'xml-compile-wss';
  1         1  
  1         11  
15              
16 1     1   1044 use XML::Compile::WSS::Util qw/:wss11 :utp11 WSM10_BASE64/;
  1         3  
  1         234  
17              
18 1     1   1641 use Digest::SHA qw/sha1_base64/;
  1         4328  
  1         139  
19 1     1   12 use Encode qw/encode/;
  1         2  
  1         170  
20 1     1   7 use MIME::Base64 qw/encode_base64/;
  1         1  
  1         61  
21 1     1   6 use POSIX qw/strftime/;
  1         1  
  1         10  
22              
23              
24             my @nonce_chars = ('A'..'Z', 'a'..'z', '0'..'9');
25 0     0     sub _random_nonce() { join '', map $nonce_chars[rand @nonce_chars], 1..5 }
26              
27             sub init($)
28 0     0 0   { my ($self, $args) = @_;
29 0   0       $args->{wss_version} ||= '1.1';
30 0           $self->SUPER::init($args);
31              
32             $self->{XCWB_username} = $args->{username}
33 0 0         or error __"no username provided for basic authentication";
34              
35             $self->{XCWB_password} = $args->{password}
36 0 0         or error __x"no password provided for basic authentication";
37              
38 0 0         my $n = defined $args->{nonce} ? $args->{nonce} : 'RANDOM';
39             my $nonce = ref $n eq 'CODE' ? $n
40             : $n eq 'RANDOM' ? \&_random_nonce
41 0 0   0     : sub { $n };
  0 0          
42              
43 0           $self->{XCWB_nonce} = $args->{nonce};
44 0   0       $self->{XCWB_wsu_id} = $args->{wsu_Id} || $args->{wsu_id};
45 0           $self->{XCWB_created} = $args->{created};
46 0   0       $self->{XCWB_pwformat} = $args->{pwformat} || UTP11_PTEXT;
47 0           $self;
48             }
49              
50             #----------------------------------
51              
52 0     0 1   sub username() {shift->{XCWB_username}}
53 0     0 1   sub password() {shift->{XCWB_password}}
54 0     0 1   sub nonce() {shift->{XCWB_nonce} }
55 0     0 1   sub wsuId() {shift->{XCWB_wsu_id} }
56 0     0 1   sub created() {shift->{XCWB_created} }
57 0     0 1   sub pwformat() {shift->{XCWB_pwformat}}
58              
59             sub prepareWriting($)
60 0     0 0   { my ($self, $schema) = @_;
61 0           $self->SUPER::prepareWriting($schema);
62 0 0         return if $self->{XCWB_login};
63              
64 0           my $nonce_type = $schema->findName('wsse:Nonce') ;
65 0           my $w_nonce = $schema->writer($nonce_type, include_namespaces => 0);
66             my $make_nonce = sub {
67 0     0     my ($doc, $nonce) = @_;
68 0           my $enc = encode_base64 $nonce;
69 0           chomp $enc;
70 0           $w_nonce->($doc, {_ => $enc, EncodingType => WSM10_BASE64});
71 0           };
72              
73 0           my $created_type = $schema->findName('wsu:Created');
74 0           my $w_created = $schema->writer($created_type, include_namespaces => 0);
75             my $make_created = sub {
76 0     0     my ($doc, $created) = @_;
77 0           $w_created->($doc, $created);
78 0           };
79              
80 0           my $pw_type = $schema->findName('wsse:Password');
81 0           my $w_pw = $schema->writer($pw_type, include_namespaces => 0);
82             my $make_pw = sub {
83 0     0     my ($doc, $password, $pwformat) = @_;
84 0           $w_pw->($doc, {_ => $password, Type => $pwformat});
85 0           };
86              
87             # UsernameToken is allowed to have an "wsu:Id" attribute
88             # We set up the writer with a hook to add that particular attribute.
89 0           my $un_type = $schema->findName('wsse:UsernameToken');
90 0           my $make_un = $schema->writer($un_type, include_namespaces => 1,
91             , hook => $self->writerHookWsuId('wsse:UsernameTokenType'));
92 0           $schema->prefixFor(WSU_10); # to get ns-decl
93              
94             $self->{XCWB_login} = sub {
95 0     0     my ($doc, $data) = @_;
96              
97 0           my %login =
98             ( wsu_Id => $self->wsuId
99             , wsse_Username => $self->username
100             );
101              
102 0   0       my $now = delete $data->{wsu_Created} || $self->created;
103 0   0       my $created = $self->dateTime($now) || '';
104 0 0         $login{$created_type} = $make_created->($doc, $created) if $created;
105              
106 0   0       my $nonce = delete $data->{wsse_Nonce} || $self->nonce || '';
107 0 0         $login{$nonce_type} = $make_nonce->($doc, $nonce)
108             if length $nonce;
109              
110 0           my $pwformat = $self->pwformat;
111 0           my $password = $self->password;
112 0 0         $created = $created->{_} if ref $created eq 'HASH';
113 0 0         $password = sha1_base64(encode utf8 => "$nonce$created$password").'='
114             if $pwformat eq UTP11_PDIGEST;
115              
116 0           $login{$pw_type} = $make_pw->($doc, $password, $pwformat);
117 0           $data->{$un_type} = $make_un->($doc, \%login);
118 0           $data;
119 0           };
120             }
121              
122             sub create($$)
123 0     0 1   { my ($self, $doc, $data) = @_;
124 0           $self->SUPER::create($doc, $data);
125 0           $self->{XCWB_login}->($doc, $data);
126             }
127              
128             1;