Skip to content

Commit eb5f293

Browse files
authored
Merge pull request #211 from waterkip/GH-move-logic
Add in_response_to to Role::ProtocolMessage
2 parents 6f7d6cb + 90d2c80 commit eb5f293

File tree

6 files changed

+116
-73
lines changed

6 files changed

+116
-73
lines changed

lib/Net/SAML2/Binding/SOAP.pm

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,22 @@ use XML::LibXML::XPathContext;
1212

1313
use Net::SAML2::XML::Sig;
1414
use Net::SAML2::XML::Util qw/ no_comments /;
15+
use Net::SAML2::Util qw/ deprecation_warning /;
1516

1617
with 'Net::SAML2::Role::VerifyXML';
1718

1819
# ABSTRACT: SOAP binding for SAML
1920

2021
=head1 SYNOPSIS
2122
22-
my $soap = Net::SAML2::Binding::SOAP->new(
23-
url => $idp_url,
24-
key => $key,
25-
cert => $cert,
26-
idp_cert => $idp_cert,
27-
);
23+
my $soap = Net::SAML2::Binding::SOAP->new(
24+
url => $idp_url,
25+
key => $key,
26+
cert => $cert,
27+
idp_cert => $idp_cert,
28+
);
2829
29-
my $response = $soap->request($req);
30+
my $response = $soap->request($req);
3031
3132
Note that LWP::UserAgent maybe used which means that environment variables
3233
may affect the use of https see:
@@ -129,14 +130,17 @@ has verify => (
129130
# expected to be an arrayref to the certificates. To avoid breaking existing
130131
# applications this changes the the cert to an arrayref if it is not
131132
# already an array ref.
133+
#
134+
# Please remove the build args logic after 6 months from april 18th 2024
132135

133136
around BUILDARGS => sub {
134137
my $orig = shift;
135138
my $self = shift;
136139

137140
my %params = @_;
138141
if ($params{idp_cert} && ref($params{idp_cert}) ne 'ARRAY') {
139-
$params{idp_cert} = [$params{idp_cert}];
142+
$params{idp_cert} = [$params{idp_cert}];
143+
deprecation_warning("Please use an array ref for idp_cert");
140144
}
141145

142146
return $self->$orig(%params);

lib/Net/SAML2/Protocol/Artifact.pm

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use strict;
2-
use warnings;
31
package Net::SAML2::Protocol::Artifact;
42
# VERSION
53

@@ -39,7 +37,7 @@ Net::SAML2::Protocol::Artifact - SAML2 artifact object
3937
=cut
4038

4139
has 'issue_instant' => (isa => DateTime, is => 'ro', required => 1);
42-
has 'in_response_to' => (isa => 'Str', is => 'ro', required => 1);
40+
has '+in_response_to' => (required => 1);
4341
has 'issuer' => (isa => 'Str', is => 'ro', required => 1);
4442
has 'status' => (isa => 'Str', is => 'ro', required => 1);
4543
has 'logoutresponse_object' => (
@@ -100,12 +98,11 @@ sub new_from_xml {
10098
}
10199

102100
my $issue_instant;
103-
104101
if (my $value = $xpath->findvalue('/samlp:ArtifactResponse/@IssueInstant')) {
105102
$issue_instant = DateTime::Format::XSD->parse_datetime($value);
106103
}
107104

108-
my $self = $class->new(
105+
return $class->new(
109106
id => $xpath->findvalue('/samlp:ArtifactResponse/@ID'),
110107
in_response_to => $xpath->findvalue('/samlp:ArtifactResponse/@InResponseTo'),
111108
issue_instant => $issue_instant,
@@ -114,8 +111,6 @@ sub new_from_xml {
114111
$response ? (response => $response) : (),
115112
$logoutresponse ? (logout_response => $logoutresponse) : (),
116113
);
117-
118-
return $self;
119114
}
120115

121116
=head2 response
@@ -140,18 +135,6 @@ sub logout_response {
140135
return $self->logoutresponse_object->toString;
141136
}
142137

143-
=head2 success( )
144-
145-
Returns true if the Response's status is Success.
146-
147-
=cut
148-
149-
sub success {
150-
my ($self) = @_;
151-
return 1 if $self->status eq $self->status_uri('success');
152-
return 0;
153-
}
154-
155138
=head2 get_response ( )
156139
157140
Returns the LogoutResponse or Response depending on which is defined

lib/Net/SAML2/Protocol/LogoutRequest.pm

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ with 'Net::SAML2::Role::ProtocolMessage';
1616

1717
=head1 SYNOPSIS
1818
19-
my $logout_req = Net::SAML2::Protocol::LogoutRequest->new(
20-
issuer => $issuer,
21-
destination => $destination,
22-
nameid => $nameid,
23-
session => $session,
24-
);
19+
my $logout_req = Net::SAML2::Protocol::LogoutRequest->new(
20+
issuer => $issuer,
21+
destination => $destination,
22+
nameid => $nameid,
23+
session => $session,
24+
);
2525
2626
=head1 METHODS
2727

lib/Net/SAML2/Protocol/LogoutResponse.pm

Lines changed: 62 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use strict;
2-
use warnings;
31
package Net::SAML2::Protocol::LogoutResponse;
42
# VERSION
53

64
use Moose;
75
use MooseX::Types::URI qw/ Uri /;
86
use Net::SAML2::XML::Util qw/ no_comments /;
7+
use Net::SAML2::Util qw/ deprecation_warning /;
98
use XML::LibXML::XPathContext;
109

1110
with 'Net::SAML2::Role::ProtocolMessage';
@@ -18,12 +17,17 @@ Net::SAML2::Protocol::LogoutResponse - the SAML2 LogoutResponse object
1817
1918
=head1 SYNOPSIS
2019
21-
my $logout_req = Net::SAML2::Protocol::LogoutResponse->new(
22-
issuer => $issuer,
23-
destination => $destination,
24-
status => $status,
25-
response_to => $response_to,
26-
);
20+
my $logout_req = Net::SAML2::Protocol::LogoutResponse->new(
21+
issuer => $issuer,
22+
destination => $destination,
23+
status => $status,
24+
response_to => $response_to,
25+
);
26+
27+
=head1 DESCRIPTION
28+
29+
This object deals with the LogoutResponse messages from SAML. It implements the
30+
role L<Net::SAML2::Role::ProtocolMessage>.
2731
2832
=head1 METHODS
2933
@@ -37,27 +41,63 @@ Arguments:
3741
3842
=item B<issuer>
3943
40-
SP's identity URI
44+
SP's identity URI (required)
4145
4246
=item B<destination>
4347
4448
IdP's identity URI
4549
4650
=item B<status>
4751
48-
response status
52+
Response status (required)
53+
54+
=item B<sub_status>
4955
50-
=item B<response_to>
56+
The sub status
5157
52-
request ID we're responding to
58+
=item B<in_response_to>
59+
60+
Request ID we're responding to (required);
5361
5462
=back
5563
5664
=cut
5765

58-
has 'status' => (isa => 'Str', is => 'ro', required => 1);
59-
has 'substatus' => (isa => 'Str', is => 'ro', required => 0);
60-
has 'response_to' => (isa => 'Str', is => 'ro', required => 1);
66+
has 'status' => (isa => 'Str', is => 'ro', required => 1);
67+
has 'sub_status' => (isa => 'Str', is => 'ro', required => 0);
68+
has '+in_response_to' => (required => 1);
69+
70+
# Remove response_to/substatus after 6 months from now (april 18th 2024)
71+
around BUILDARGS => sub {
72+
my $orig = shift;
73+
my $self = shift;
74+
my %args = @_;
75+
76+
if (my $irt = delete $args{response_to}) {
77+
$args{in_response_to} = $irt;
78+
deprecation_warning(
79+
"Please use in_response_to instead of response_to");
80+
}
81+
82+
if (my $s = delete $args{substatus}) {
83+
$args{sub_status} = $s;
84+
deprecation_warning(
85+
"Please use in_response_to instead of response_to");
86+
}
87+
return $self->$orig(%args);
88+
};
89+
90+
sub response_to {
91+
my $self = shift;
92+
deprecation_warning("Please use in_response_to instead of response_to");
93+
return $self->in_response_to;
94+
}
95+
96+
sub substatus {
97+
my $self = shift;
98+
deprecation_warning("Please use sub_status instead of substatus");
99+
return $self->sub_status;
100+
}
61101

62102
=head2 new_from_xml( ... )
63103
@@ -86,12 +126,12 @@ sub new_from_xml {
86126

87127
my $self = $class->new(
88128
id => $xpath->findvalue('/samlp:LogoutResponse/@ID'),
89-
response_to => $xpath->findvalue('/samlp:LogoutResponse/@InResponseTo'),
129+
in_response_to => $xpath->findvalue('/samlp:LogoutResponse/@InResponseTo'),
90130
destination => $xpath->findvalue('/samlp:LogoutResponse/@Destination'),
91131
session => $xpath->findvalue('/samlp:LogoutResponse/samlp:SessionIndex'),
92132
issuer => $xpath->findvalue('/samlp:LogoutResponse/saml:Issuer'),
93133
status => $xpath->findvalue('/samlp:LogoutResponse/samlp:Status/samlp:StatusCode/@Value'),
94-
substatus => $xpath->findvalue('/samlp:LogoutResponse/samlp:Status/samlp:StatusCode/samlp:StatusCode/@Value'),
134+
sub_status => $xpath->findvalue('/samlp:LogoutResponse/samlp:Status/samlp:StatusCode/samlp:StatusCode/@Value'),
95135
);
96136

97137
return $self;
@@ -117,7 +157,7 @@ sub as_xml {
117157
Version => '2.0',
118158
IssueInstant => $self->issue_instant,
119159
Destination => $self->destination,
120-
InResponseTo => $self->response_to },
160+
InResponseTo => $self->in_response_to },
121161
$x->Issuer(
122162
$saml,
123163
$self->issuer,
@@ -133,16 +173,10 @@ sub as_xml {
133173
);
134174
}
135175

136-
=head2 success( )
176+
__PACKAGE__->meta->make_immutable;
137177

138-
Returns true if the Response's status is Success.
178+
__END__
139179
140-
=cut
180+
=head1 SEE ALSO
141181
142-
sub success {
143-
my ($self) = @_;
144-
return 1 if $self->status eq $self->status_uri('success');
145-
return 0;
146-
}
147-
148-
__PACKAGE__->meta->make_immutable;
182+
=head2 L<Net::SAML2::Roles::ProtocolMessage>

lib/Net/SAML2/Role/ProtocolMessage.pm

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
use strict;
2-
use warnings;
31
package Net::SAML2::Role::ProtocolMessage;
42
# VERSION
53

64
use Moose::Role;
75

86
# ABSTRACT: Common behaviour for Protocol messages
97

8+
use feature qw(state);
9+
1010
use namespace::autoclean;
1111

1212
use DateTime;
1313
use MooseX::Types::URI qw/ Uri /;
1414
use Net::SAML2::Util qw(generate_id);
1515
use Net::SAML2::Types qw(XsdID);
16+
use URN::OASIS::SAML2 qw(:status);
1617

1718
=head1 NAME
1819
@@ -66,6 +67,12 @@ has destination => (
6667
predicate => 'has_destination',
6768
);
6869

70+
has in_response_to => (
71+
isa => XsdID,
72+
is => 'ro',
73+
predicate => 'has_in_response_to',
74+
);
75+
6976
sub _build_issue_instant {
7077
return DateTime->now(time_zone => 'UTC')->strftime('%FT%TZ');
7178
}
@@ -112,25 +119,34 @@ Legal short names for B<$status> are:
112119
113120
=item C<responder>
114121
122+
=item C<partial>
123+
115124
=back
116125
117126
=cut
118127

128+
119129
sub status_uri {
120130
my ($self, $status) = @_;
121131

122-
my $statuses = {
123-
success => 'urn:oasis:names:tc:SAML:2.0:status:Success',
124-
requester => 'urn:oasis:names:tc:SAML:2.0:status:Requester',
125-
responder => 'urn:oasis:names:tc:SAML:2.0:status:Responder',
132+
state $statuses = {
133+
success => STATUS_SUCCESS(),
134+
requester => STATUS_REQUESTER(),
135+
responder => STATUS_RESPONDER(),
126136
partial => 'urn:oasis:names:tc:SAML:2.0:status:PartialLogout',
127137
};
128138

129-
if (exists $statuses->{$status}) {
130-
return $statuses->{$status};
131-
}
132-
139+
return $statuses->{$status} if exists $statuses->{$status};
133140
return;
134141
}
135142

143+
sub success {
144+
my $self = shift;
145+
146+
return $self->status eq STATUS_SUCCESS() if $self->can('status');
147+
croak(
148+
"You haven't implemented the status method, unable to determine success"
149+
);
150+
}
151+
136152
1;

t/21-artifact-response.t

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,13 @@ isa_ok($logout, "Net::SAML2::Protocol::LogoutResponse");
127127

128128
ok($logout->success(), "Logout Response has a Success");
129129

130-
is($logout->response_to, 'NETSAML2_0b499739aa1d76eb80093a068053b8fee62cade60f7dc27826d0f13b19cad16a', "Logout Response InResponseTo - ok");
130+
is($logout->in_response_to, 'NETSAML2_0b499739aa1d76eb80093a068053b8fee62cade60f7dc27826d0f13b19cad16a', "Logout Response InResponseTo - ok");
131+
132+
{
133+
# TODO: Remove once response_to has been eradicated
134+
local $SIG{__WARN__} = sub { }; # Suppress the warning in the testsuite
135+
is($logout->response_to, $logout->in_response_to, ".. and old method still works");
136+
}
131137

132138
is($logout->id, 'ID_bfc25851-4da2-4420-8240-9103b77b12dc', "Logout Response Id - ok");
133139

@@ -139,6 +145,6 @@ isa_ok($logout, "Net::SAML2::Protocol::LogoutResponse", "from get_response");
139145

140146
ok($logout->success(), "Logout Response has a Success");
141147

142-
is($logout->response_to, 'NETSAML2_0b499739aa1d76eb80093a068053b8fee62cade60f7dc27826d0f13b19cad16a', "Logout Response InResponseTo - ok");
148+
is($logout->in_response_to, 'NETSAML2_0b499739aa1d76eb80093a068053b8fee62cade60f7dc27826d0f13b19cad16a', "Logout Response InResponseTo - ok");
143149

144150
done_testing;

0 commit comments

Comments
 (0)