BEGIN {
require
't/test-lib.pm'
;
require
't/saml-lib.pm'
;
require
't/smtp.pm'
;
}
my
$maintests
= 18;
my
$debug
=
'error'
;
my
(
$issuer
,
$sp
,
$res
);
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
;
}
my
$file
=
"$main::tmpDir/20170531_dwho_dGVzdHJlZjI=.json"
;
open
F,
"> $file"
or
die
($!);
print
F '[
{
"uid"
:
"dwho"
,
"date"
:
"2017-05-31"
,
"reference"
:
"testref2"
,
"title"
:
"Test title"
,
"subtitle"
:
"Test subtitle"
,
"text"
:
"This is a test text"
,
"check"
: [
"Accept test"
,
"Accept test2"
]
}
]';
close
F;
$issuer
= register(
'issuer'
, \
&issuer
);
$sp
= register(
'sp'
, \
&sp
);
ok(
$res
=
$sp
->_get(
'/'
,
accept
=>
'text/html'
,
),
'Unauth SP request'
);
expectOK(
$res
);
my
(
$host
,
$url
,
$s
) =
expectAutoPost(
$res
,
'auth.idp.com'
,
'/saml/singleSignOn'
,
'SAMLRequest'
);
ok(
$res
=
$issuer
->_post(
$url
,
IO::String->new(
$s
),
accept
=>
'text/html'
,
length
=>
length
(
$s
)
),
'Post SAML request to IdP'
);
expectOK(
$res
);
my
$pdata
=
'lemonldappdata='
. expectCookie(
$res
,
'lemonldappdata'
);
$s
=
"user=dwho&password=dwho&$s"
;
ok(
$res
=
$issuer
->_post(
$url
,
IO::String->new(
$s
),
accept
=>
'text/html'
,
cookie
=>
$pdata
,
length
=>
length
(
$s
),
),
'Post authentication'
);
(
$host
,
$url
,
$s
) =
expectForm(
$res
,
undef
,
'/mail2fcheck?skin=bootstrap'
,
'token'
,
'code'
);
ok(
$res
->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%
,
'Found EXTCODE input'
) or
print
STDERR Dumper(
$res
->[2]->[0] );
ok( mail() =~ m%<b>(\d{4})</b>%,
'Found 2F code in mail'
)
or
print
STDERR Dumper( mail() );
my
$code
= $1;
$s
=~ s/code=/code=${code}/;
ok(
$res
=
$issuer
->_post(
'/mail2fcheck'
,
IO::String->new(
$s
),
length
=>
length
(
$s
),
cookie
=>
$pdata
,
accept
=>
'text/html'
,
),
'Post code'
);
my
$idpId
= expectCookie(
$res
);
$pdata
=
'lemonldappdata='
. expectCookie(
$res
,
'lemonldappdata'
);
(
$host
,
$url
,
$s
) =
expectForm(
$res
,
undef
,
'/notifback'
,
'reference1x1'
);
ok(
$res
=
$issuer
->_post(
'/notifback'
,
IO::String->new(
$s
),
cookie
=>
"lemonldap=$idpId; $pdata"
,
accept
=>
'text/html'
,
length
=>
length
(
$s
),
),
"Accept notification"
);
$idpId
= expectCookie(
$res
);
$file
=~ s/json$/done/;
ok( -e
$file
,
'Notification was deleted'
);
$pdata
=
'lemonldappdata='
. expectCookie(
$res
,
'lemonldappdata'
);
ok(
$res
=
$issuer
->_get(
'/saml'
,
cookie
=>
"lemonldap=$idpId; $pdata"
,
accept
=>
'text/html'
,
),
'Follow redirection'
);
$pdata
= expectCookie(
$res
,
'lemonldappdata'
);
ok(
$pdata
!~
'issuerRequestsaml'
,
'SAML request cleared from pdata'
);
(
$host
,
$url
,
$s
) =
expectAutoPost(
$res
,
'auth.sp.com'
,
'/saml/proxySingleSignOnPost'
,
'SAMLResponse'
);
ok(
$res
=
$sp
->_post(
$url
, IO::String->new(
$s
),
accept
=>
'text/html'
,
length
=>
length
(
$s
),
),
'Post SAML response to SP'
);
my
$spId
= expectCookie(
$res
);
ok(
$res
=
$sp
->_get(
'/'
,
cookie
=>
"lemonldap=$spId"
),
'Get / on SP'
);
expectOK(
$res
);
expectAuthenticatedAs(
$res
,
'dwho@badwolf.org@idp'
);
ok(
$res
=
$sp
->_get(
'/'
,
query
=>
'logout'
,
cookie
=>
"lemonldap=$spId"
,
accept
=>
'text/html'
),
'Query SP for logout'
);
(
$host
,
$url
,
$s
) =
expectAutoPost(
$res
,
'auth.idp.com'
,
'/saml/singleLogout'
,
'SAMLRequest'
);
ok(
$res
=
$issuer
->_post(
$url
,
IO::String->new(
$s
),
accept
=>
'text/html'
,
cookie
=>
"lemonldap=$idpId"
,
length
=>
length
(
$s
)
),
'Post SAML logout request to IdP'
);
(
$host
,
$url
,
$s
) =
expectAutoPost(
$res
,
'auth.sp.com'
,
'/saml/proxySingleLogoutReturn'
,
'SAMLResponse'
);
my
$removedCookie
= expectCookie(
$res
);
is(
$removedCookie
, 0,
"SSO cookie removed"
);
ok(
$res
=
$sp
->_post(
$url
, IO::String->new(
$s
),
accept
=>
'text/html'
,
length
=>
length
(
$s
),
),
'Post SAML response to SP'
);
ok(
$res
=
$issuer
->_get(
'/'
,
cookie
=>
"lemonldap=$idpId"
,
),
'Test if user is reject on IdP'
);
expectReject(
$res
);
ok(
$res
=
$sp
->_get(
'/'
,
accept
=>
'text/html'
,
cookie
=>
"lemonldap=$spId"
),
'Test if user is reject on SP'
);
expectOK(
$res
);
expectAutoPost(
$res
,
'auth.idp.com'
,
'/saml/singleSignOn'
,
'SAMLRequest'
);
unlink
$file
;
}
count(
$maintests
);
clean_sessions();
done_testing( count() );
sub
issuer {
return
LLNG::Manager::Test->new(
{
ini
=> {
logLevel
=>
$debug
,
domain
=>
'idp.com'
,
authentication
=>
'Demo'
,
userDB
=>
'Same'
,
issuerDBSAMLActivation
=> 1,
mail2fActivation
=> 1,
mail2fCodeRegex
=>
'\d{4}'
,
notification
=> 1,
notificationStorage
=>
'File'
,
notificationStorageOptions
=> {
dirName
=>
"$main::tmpDir"
},
oldNotifFormat
=> 0,
samlSPMetaDataOptions
=> {
'sp.com'
=> {
samlSPMetaDataOptionsEncryptionMode
=>
'none'
,
samlSPMetaDataOptionsSignSSOMessage
=> 1,
samlSPMetaDataOptionsSignSLOMessage
=> 1,
samlSPMetaDataOptionsCheckSSOMessageSignature
=> 1,
samlSPMetaDataOptionsCheckSLOMessageSignature
=> 1,
}
},
samlSPMetaDataExportedAttributes
=> {
'sp.com'
=> {
cn
=>
'1;cn;urn:oasis:names:tc:SAML:2.0:attrname-format:basic'
,
uid
=>
'1;uid;urn:oasis:names:tc:SAML:2.0:attrname-format:basic'
,
}
},
samlOrganizationDisplayName
=>
"IDP"
,
samlOrganizationName
=>
"IDP"
,
samlServicePrivateKeyEnc
=> saml_key_idp_private_enc,
samlServicePrivateKeySig
=> saml_key_idp_private_sig,
samlServicePublicKeyEnc
=> saml_key_idp_public_enc,
samlServicePublicKeySig
=> saml_key_idp_public_sig,
samlSPMetaDataXML
=> {
"sp.com"
=> {
samlSPMetaDataXML
=>
samlSPMetaDataXML(
'sp'
,
'HTTP-POST'
)
},
},
}
}
);
}
sub
sp {
return
LLNG::Manager::Test->new(
{
ini
=> {
logLevel
=>
$debug
,
domain
=>
'sp.com'
,
authentication
=>
'SAML'
,
userDB
=>
'Same'
,
issuerDBSAMLActivation
=> 0,
restSessionServer
=> 1,
samlIDPMetaDataExportedAttributes
=> {
idp
=> {
mail
=>
"0;mail;;"
,
uid
=>
"1;uid"
,
cn
=>
"0;cn"
}
},
samlIDPMetaDataOptions
=> {
idp
=> {
samlIDPMetaDataOptionsEncryptionMode
=>
'none'
,
samlIDPMetaDataOptionsSSOBinding
=>
'post'
,
samlIDPMetaDataOptionsSLOBinding
=>
'post'
,
samlIDPMetaDataOptionsSignSSOMessage
=> 1,
samlIDPMetaDataOptionsSignSLOMessage
=> 1,
samlIDPMetaDataOptionsCheckSSOMessageSignature
=> 1,
samlIDPMetaDataOptionsCheckSLOMessageSignature
=> 1,
samlIDPMetaDataOptionsForceUTF8
=> 1,
}
},
samlIDPMetaDataExportedAttributes
=> {
idp
=> {
"uid"
=>
"0;uid;;"
,
"cn"
=>
"1;cn;;"
,
},
},
samlIDPMetaDataXML
=> {
idp
=> {
samlIDPMetaDataXML
=>
samlIDPMetaDataXML(
'idp'
,
'HTTP-POST'
)
}
},
samlOrganizationDisplayName
=>
"SP"
,
samlOrganizationName
=>
"SP"
,
samlServicePublicKeySig
=> saml_key_sp_public_sig,
samlServicePrivateKeyEnc
=> saml_key_sp_private_enc,
samlServicePrivateKeySig
=> saml_key_sp_private_sig,
samlServicePublicKeyEnc
=> saml_key_sp_public_enc,
samlSPSSODescriptorAuthnRequestsSigned
=> 1,
},
}
);
}