File Coverage

blib/lib/Net/SAML2/Protocol/LogoutRequest.pm
Criterion Covered Total %
statement 36 36 100.0
branch 13 18 72.2
condition n/a
subroutine 9 9 100.0
pod 2 2 100.0
total 60 65 92.3


line stmt bran cond sub pod time code
1             package Net::SAML2::Protocol::LogoutRequest;
2 26     26   202 use Moose;
  26         67  
  26         244  
3              
4             our $VERSION = '0.74'; # VERSION
5              
6 26     26   184932 use MooseX::Types::Common::String qw/ NonEmptySimpleStr /;
  26         76  
  26         388  
7 26     26   78220 use MooseX::Types::URI qw/ Uri /;
  26         66  
  26         296  
8 26     26   47045 use Net::SAML2::XML::Util qw/ no_comments /;
  26         75  
  26         1715  
9 26     26   209 use XML::Generator;
  26         70  
  26         291  
10 26     26   1533 use URN::OASIS::SAML2 qw(:urn);
  26         66  
  26         4211  
11 26     26   220 use XML::LibXML::XPathContext;
  26         92  
  26         17210  
12              
13             with 'Net::SAML2::Role::ProtocolMessage';
14              
15             # ABSTRACT: SAML2 LogoutRequest Protocol object
16              
17              
18             has 'session' => (isa => NonEmptySimpleStr, is => 'ro', required => 1);
19             has 'nameid' => (isa => NonEmptySimpleStr, is => 'ro', required => 1);
20             has 'nameid_format' => (
21             isa => NonEmptySimpleStr,
22             is => 'ro',
23             required => 0,
24             predicate => 'has_nameid_format'
25             );
26             has 'destination' => (
27             isa => NonEmptySimpleStr,
28             is => 'ro',
29             required => 0,
30             predicate => 'has_destination'
31             );
32              
33             has sp_provided_id => (
34             isa => NonEmptySimpleStr,
35             is => 'ro',
36             required => 0,
37             predicate => 'has_sp_provided_id'
38             );
39              
40             has affiliation_group_id => (
41             isa => NonEmptySimpleStr,
42             is => 'ro',
43             required => 0,
44             predicate => 'has_affiliation_group_id'
45             );
46              
47             has name_qualifier => (
48             isa => NonEmptySimpleStr,
49             is => 'ro',
50             required => 0,
51             predicate => 'has_name_qualifier'
52             );
53             has include_name_qualifier =>
54             (isa => 'Bool', is => 'ro', required => 0, default => 0);
55              
56             around BUILDARGS => sub {
57             my $orig = shift;
58             my $self = shift;
59             my %args = @_;
60              
61             if ($args{nameid_format} && $args{nameid_format} eq 'urn:oasis:names:tc:SAML:2.0:nameidformat:persistent') {
62             $args{include_name_qualifier} = 1;
63             }
64              
65             return $self->$orig(%args);
66             };
67              
68              
69              
70             sub new_from_xml {
71 1     1 1 1396 my ($class, %args) = @_;
72              
73 1         6 my $dom = no_comments($args{xml});
74              
75 1         14 my $xpath = XML::LibXML::XPathContext->new($dom);
76 1         9 $xpath->registerNs('saml', URN_ASSERTION);
77 1         6 $xpath->registerNs('samlp', URN_PROTOCOL);
78              
79 1         4 my %params = (
80             id => $xpath->findvalue('/samlp:LogoutRequest/@ID'),
81             session => $xpath->findvalue('/samlp:LogoutRequest/samlp:SessionIndex'),
82             issuer => $xpath->findvalue('/samlp:LogoutRequest/saml:Issuer'),
83             nameid => $xpath->findvalue('/samlp:LogoutRequest/saml:NameID'),
84             destination => $xpath->findvalue('/samlp:LogoutRequest/@Destination'),
85             );
86              
87 1         303 my $nameid_format
88             = $xpath->findvalue('/samlp:LogoutRequest/saml:NameID/@Format');
89              
90 1 50       105 $params{nameid_format} = $nameid_format
91             if NonEmptySimpleStr->check($nameid_format);
92              
93             $params{include_name_qualifier} = $args{include_name_qualifier}
94 1 50       940 if $args{include_name_qualifier};
95              
96 1         86 return $class->new(%params);
97             }
98              
99              
100             sub as_xml {
101 6     6 1 1761 my $self = shift;
102              
103 6         41 my $x = XML::Generator->new(':pretty=0');
104 6         712 my $saml = ['saml' => URN_ASSERTION];
105 6         21 my $samlp = ['samlp' => URN_PROTOCOL];
106              
107              
108 6 50       235 $x->xml(
    50          
    100          
    50          
    100          
    100          
    100          
109             $x->LogoutRequest(
110             $samlp,
111             {
112             ID => $self->id,
113             IssueInstant => $self->issue_instant,
114             $self->has_destination
115             ? (Destination => $self->destination)
116             : (),
117             Version => '2.0'
118             },
119             $x->Issuer($saml, $self->issuer),
120             $x->NameID(
121             $saml,
122             {
123             $self->has_nameid_format
124             ? (Format => $self->nameid_format)
125             : (),
126             $self->has_sp_provided_id ? (
127             SPProvidedID => $self->sp_provided_id
128             ) : (),
129             $self->include_name_qualifier
130             ? (
131             $self->has_name_qualifier
132             ? (NameQualifier => $self->name_qualifier)
133             : ($self->has_destination ? (NameQualifier => $self->destination) : ()),
134             SPNameQualifier =>
135             $self->has_affiliation_group_id ? $self->affiliation_group_id : $self->issuer
136             )
137             : (),
138             },
139             $self->nameid
140             ),
141             $x->SessionIndex($samlp, $self->session),
142             )
143             );
144             }
145              
146             __PACKAGE__->meta->make_immutable;
147              
148             __END__
149              
150             =pod
151              
152             =encoding UTF-8
153              
154             =head1 NAME
155              
156             Net::SAML2::Protocol::LogoutRequest - SAML2 LogoutRequest Protocol object
157              
158             =head1 VERSION
159              
160             version 0.74
161              
162             =head1 SYNOPSIS
163              
164             my $logout_req = Net::SAML2::Protocol::LogoutRequest->new(
165             issuer => $issuer,
166             destination => $destination,
167             nameid => $nameid,
168             session => $session,
169             );
170              
171             =head1 METHODS
172              
173             =head2 new( ... )
174              
175             Constructor. Returns an instance of the LogoutRequest object.
176              
177             Arguments:
178              
179             =over
180              
181             =item B<session>
182              
183             Session to log out
184              
185             =item B<nameid>
186              
187             NameID of the user to log out
188              
189             =item B<destination>
190              
191             IdP's identity URI this is required for a signed message but likely should be
192             sent regardless
193              
194             =back
195              
196             The following options alter the output of the NameID element
197              
198             =over
199              
200             =item B<nameid_format>
201              
202             When supplied adds the Format attribute to the NameID
203              
204             =item B<sp_provided_id>
205              
206             When supplied adds the SPProvidedID attribute to the NameID
207              
208             =item B<include_name_qualifier>
209              
210             Tell the module to include the NameQualifier and SPNameQualifier attributes in
211             the NameID. Defaults to false unless the B<nameid_format> equals
212             C<urn:oasis:names:tc:SAML:2.0:nameidformat:persistent>
213              
214             =item B<name_qualifier>
215              
216             When supplied sets the NameQualifier attribute. When not supplied, this
217             defaults to the destination.
218              
219             =item B<affiliation_group_id>
220              
221             When supplied sets the SPNameQualifier attribute. When not supplied, this
222             defaults to the issuer.
223              
224             =back
225              
226             =head2 new_from_xml( ... )
227              
228             Create a LogoutRequest object from the given XML.
229              
230             Arguments:
231              
232             =over
233              
234             =item B<xml>
235              
236             XML data
237              
238             =back
239              
240             =head2 as_xml( )
241              
242             Returns the LogoutRequest as XML.
243              
244             =head1 AUTHORS
245              
246             =over 4
247              
248             =item *
249              
250             Chris Andrews <chrisa@cpan.org>
251              
252             =item *
253              
254             Timothy Legge <timlegge@gmail.com>
255              
256             =back
257              
258             =head1 COPYRIGHT AND LICENSE
259              
260             This software is copyright (c) 2023 by Venda Ltd, see the CONTRIBUTORS file for others.
261              
262             This is free software; you can redistribute it and/or modify it under
263             the same terms as the Perl 5 programming language system itself.
264              
265             =cut