use lib 'inc'; use Test::More; use strict; use IO::String; use LWP::UserAgent; use LWP::Protocol::PSGI; use MIME::Base64; BEGIN { require 't/test-lib.pm'; require 't/saml-lib.pm'; } my $maintests = 30; my $debug = 'error'; my ( $issuer, $sp, $sp2, $sp3, $res ); # Redefine LWP methods for tests LWP::Protocol::PSGI->register( sub { my $req = Plack::Request->new(@_); fail('POST should not launch SOAP requests'); count(1); return [ 500, [], [] ]; } ); SKIP: { eval "use Lasso"; if ($@) { skip 'Lasso not found', $maintests; } # Initialization $issuer = register( 'issuer', \&issuer ); $sp = register( 'sp', \&sp ); $sp2 = register( 'sp2', \&sp2 ); $sp3 = register( 'sp3', \&sp3 ); # Simple SP access my $res; ok( $res = $sp->_get( '/', accept => 'text/html', query => 'url=aHR0cDovL3Rlc3QxLmV4YW1wbGUuY29tLw==' ), 'Unauth SP request' ); my ( $host, $url, $query ); ( $url, $query ) = expectRedirection( $res, qr#^http://auth.idp.com(/saml/singleSignOn)\?(SAMLRequest=.+)# ); # Push SAML request to IdP switch ('issuer'); ok( $res = $issuer->_get( $url, query => $query, accept => 'text/html', ), 'Launch SAML request to IdP' ); expectOK($res); my $pdata = 'lemonldappdata=' . expectCookie( $res, 'lemonldappdata' ); # Try to authenticate to IdP my $body = $res->[2]->[0]; $body =~ s/^.*?//s; $body =~ s#.*$##s; my %fields = ( $body =~ /_get("/sessions/global/$spId"), 'Get UTF-8' ); expectOK($res); ok( $res = eval { JSON::from_json( $res->[2]->[0] ) }, ' GET JSON' ) or print STDERR $@; ok( $res->{cn} eq 'Frédéric Accents', 'UTF-8 values' ) or explain( $res, 'cn => Frédéric Accents' ); # Simple SP2 access switch ('sp2'); ok( $res = $sp2->_get( '/', accept => 'text/html', query => 'url=aHR0cDovL3Rlc3QxLmV4YW1wbGUuY29tLw==' ), 'Unauth SP2 request' ); ( $url, $query ) = expectRedirection( $res, qr#^http://auth.idp.com(/saml/singleSignOn)\?(SAMLRequest=.+)# ); # Push SAML request to IdP switch ('issuer'); ok( $res = $issuer->_get( $url, query => $query, accept => 'text/html', cookie => "lemonldap=$idpId", ), 'Launch SAML request to IdP' ); ( $host, $url, $query ) = expectForm( $res, 'auth.sp2.com', '/saml/proxySingleSignOnPost', 'SAMLResponse', 'RelayState' ); # Post SAML response to SP2 switch ('sp2'); ok( $res = $sp2->_post( $url, IO::String->new($query), accept => 'text/html', length => length($query), ), 'Post SAML response to SP2' ); my $sp2Id = expectCookie($res); expectRedirection( $res, 'http://test1.example.com/' ); ok( $res = $sp2->_get( '/', cookie => "lemonldap=$spId" ), 'Get / on SP2' ); expectOK($res); expectAuthenticatedAs( $res, 'fa@badwolf.org@idp' ); # Simple SP3 access switch ('sp3'); ok( $res = $sp3->_get( '/', accept => 'text/html', query => 'url=aHR0cDovL3Rlc3QxLmV4YW1wbGUuY29tLw==' ), 'Unauth SP3 request' ); ( $url, $query ) = expectRedirection( $res, qr#^http://auth.idp.com(/saml/singleSignOn)\?(SAMLRequest=.+)# ); # Push SAML request to IdP switch ('issuer'); ok( $res = $issuer->_get( $url, query => $query, accept => 'text/html', cookie => "lemonldap=$idpId", ), 'Launch SAML request to IdP' ); ( $host, $url, $query ) = expectForm( $res, 'auth.sp3.com', '/saml/proxySingleSignOnPost', 'SAMLResponse', 'RelayState' ); # Post SAML response to SP3 switch ('sp3'); ok( $res = $sp3->_post( $url, IO::String->new($query), accept => 'text/html', length => length($query), ), 'Post SAML response to SP3' ); my $sp3Id = expectCookie($res); expectRedirection( $res, 'http://test1.example.com/' ); ok( $res = $sp3->_get( '/', cookie => "lemonldap=$spId" ), 'Get / on SP3' ); expectOK($res); expectAuthenticatedAs( $res, 'fa@badwolf.org@idp' ); # Logout initiated by SP ok( $res = $sp->_get( '/', query => 'logout', cookie => "lemonldap=$spId", accept => 'text/html' ), 'Query SP for logout' ); ( $url, $query ) = expectRedirection( $res, qr#^http://auth.idp.com(/saml/singleLogout)\?(SAMLRequest=.+)# ); # Push SAML logout request to IdP switch ('issuer'); ok( $res = $issuer->_get( $url, query => $query, accept => 'text/html', cookie => "lemonldap=$idpId", ), 'Launch SAML logout request to IdP' ); my $removedCookie = expectCookie($res); is( $removedCookie, 0, "SSO cookie removed" ); my $relaypage = $res; my %iframes = $res->[2]->[0] =~ m%