Merge branch 'v2.0'
This commit is contained in:
commit
01b5951b73
3
Makefile
3
Makefile
|
@ -551,6 +551,8 @@ launch_protractor:
|
|||
# Start e2e tests
|
||||
# NB: you must have protractor installed (using npm install -g protractor)
|
||||
# and have run update-webdriver at least once and have a node.js > 4.0
|
||||
# Install test keys
|
||||
cp -f e2e-tests/persistent/5efe8af397fc3577e05b483aca964f1b.e2e-test e2e-tests/conf/persistents/5efe8af397fc3577e05b483aca964f1b
|
||||
@E2E_TESTS=$(E2E_TESTS) TESTWEBSERVERPORT=$(TESTWEBSERVERPORT) protractor e2e-tests/protractor-conf.js
|
||||
|
||||
stop_web_server:
|
||||
|
@ -599,6 +601,7 @@ install_bin: install_conf_dir
|
|||
@cp -f\
|
||||
${SRCHANDLERDIR}/eg/scripts/purgeLocalCache \
|
||||
${SRCPORTALDIR}/site/cron/purgeCentralCache \
|
||||
${SRCPORTALDIR}/scripts/llngDeleteSession \
|
||||
${SRCCOMMONDIR}/scripts/convertConfig \
|
||||
${SRCCOMMONDIR}/scripts/lmMigrateConfFiles2ini \
|
||||
${SRCCOMMONDIR}/scripts/rotateOidcKeys \
|
||||
|
|
4
RELEASE
4
RELEASE
|
@ -28,7 +28,7 @@ Before release
|
|||
|
||||
Replace https://lemonldap-ng.org/documentation/X.X/parameterlist by
|
||||
/tmp/prmlist.txt content
|
||||
|
||||
|
||||
$ make documentation
|
||||
|
||||
- Update changelog:
|
||||
|
@ -56,7 +56,7 @@ For major release
|
|||
|
||||
- Go on gitlab and create a new tag: https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/tags/new
|
||||
|
||||
- Change "latest" symlink in dokuwiki
|
||||
- Change "latest" symlink in dokuwiki
|
||||
|
||||
- Edit scripts/doc.pl in trunk to point on the new documentation path
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@
|
|||
"default" : "accept"
|
||||
},
|
||||
"manager.__DNSDOMAIN__" : {
|
||||
"(?#Configuration)^/(manager\\.html|$)" : "$uid eq \"dwho\"",
|
||||
"(?#Configuration)^/(manager\\.html|conf|$)" : "$uid eq \"dwho\"",
|
||||
"(?#Notifications)/notifications" : "$uid eq \"dwho\" or $uid eq \"rtyler\"",
|
||||
"(?#Sessions)/sessions" : "$uid eq \"dwho\" or $uid eq \"rtyler\"",
|
||||
"default" : "$uid eq \"dwho\" or $uid eq \"rtyler\""
|
||||
|
|
16
changelog
16
changelog
|
@ -765,7 +765,7 @@ lemonldap-ng (1.4.0) stable; urgency=low
|
|||
* [LEMONLDAP-712] - strange behaviour with session cache
|
||||
* [LEMONLDAP-386] - use LL::NG::Handler instead of custom perl module in apache config
|
||||
* [LEMONLDAP-430] - httpSession and updateSession + deleteSessionFromLocalStorage optimization
|
||||
* [LEMONLDAP-591] - Portal should refresh their configuration cache on expiration
|
||||
* [LEMONLDAP-591] - Portal should refresh their configuration cache on expiration
|
||||
* [LEMONLDAP-600] - Rewrite object libs with Moo or Mouse
|
||||
* [LEMONLDAP-636] - Manage exported variables per UserDB module
|
||||
* [LEMONLDAP-648] - Build French documentation in Makefile
|
||||
|
@ -868,7 +868,7 @@ lemonldap-ng (1.3.0) stable; urgency=low
|
|||
Common
|
||||
* [LEMONLDAP-412] - Passwrd policy expiration warning time not friendly
|
||||
displayed
|
||||
* [LEMONLDAP-493] - Make LL::NG's rpm spec file more portable
|
||||
* [LEMONLDAP-493] - Make LL::NG's rpm spec file more portable
|
||||
* [LEMONLDAP-500] - do not burden config in memory with useless things
|
||||
* [LEMONLDAP-524] - minimize weight of relaystate in SAML session backend
|
||||
* [LEMONLDAP-559] - Refine useXForwardedForIP option by setting trusted
|
||||
|
@ -900,7 +900,7 @@ lemonldap-ng (1.3.0) stable; urgency=low
|
|||
session
|
||||
* [LEMONLDAP-613] - Log applied rule in debug mode
|
||||
* [LEMONLDAP-615] - Add AuthGoogle module
|
||||
* [LEMONLDAP-617] - [SAML] Allow to skip the IDP selection
|
||||
* [LEMONLDAP-617] - [SAML] Allow to skip the IDP selection
|
||||
* [LEMONLDAP-621] - Config storage in JSON file
|
||||
* [LEMONLDAP-623] - WebID authentication and user DB modules
|
||||
* [LEMONLDAP-632] - Rename liblemonldap-ng-conf-perl to
|
||||
|
@ -1065,7 +1065,7 @@ lemonldap-ng (1.2.0) stable; urgency=low
|
|||
* [LEMONLDAP-371] - custom function declaration doesn't work through
|
||||
management UI
|
||||
* [LEMONLDAP-373] - Field values lost in manager
|
||||
* [LEMONLDAP-375] - empty query string in redirect url
|
||||
* [LEMONLDAP-375] - empty query string in redirect url
|
||||
* [LEMONLDAP-376] - wrong authentication mode stored in session with
|
||||
authMulti when SSLRequire set to 0
|
||||
* [LEMONLDAP-380] - Mail reset session not destroyed when password is
|
||||
|
@ -1105,7 +1105,7 @@ lemonldap-ng (1.2.0) stable; urgency=low
|
|||
* [LEMONLDAP-446] - Server error when a password mail reset session is
|
||||
unavailable and the token is passed to mail.pl
|
||||
* [LEMONLDAP-447] - Bad identifier in grantSession logs
|
||||
* [LEMONLDAP-448] - defined(%hash) is deprecated
|
||||
* [LEMONLDAP-448] - defined(%hash) is deprecated
|
||||
* [LEMONLDAP-450] - SAML Authn not working with binding HTTP Redirect
|
||||
* [LEMONLDAP-454] - Replace $ip with client IP in forging HTTP headers
|
||||
doesn't work
|
||||
|
@ -1280,14 +1280,14 @@ lemonldap-ng (1.1.0) stable; urgency=low
|
|||
* [LEMONLDAP-348] - Possibility to access menu tab with an URL
|
||||
|
||||
lemonldap-ng (1.0.6) stable; urgency=low
|
||||
|
||||
|
||||
* [LEMONLDAP-297] - LDAP attributes are not explicitely requested
|
||||
* [LEMONLDAP-298] - Multi option with # not accepted in Manager
|
||||
* [LEMONLDAP-304] - Cannot use spaces between values of Multi
|
||||
authentication
|
||||
parameter
|
||||
* [LEMONLDAP-305] - Parameters are not overriden in the first Multi module
|
||||
* [LEMONLDAP-307] - Base64 encoded IDs can contain more than one "/", but
|
||||
* [LEMONLDAP-307] - Base64 encoded IDs can contain more than one "/", but
|
||||
only the first is escaped
|
||||
|
||||
lemonldap-ng (1.0.5) stable; urgency=low
|
||||
|
@ -1983,7 +1983,7 @@ lemonldap-ng (0.7b11) unstable; urgency=low
|
|||
* New features:
|
||||
- Cross Domain Authentication
|
||||
- SOAP configuration access
|
||||
- READMEs and documentation update
|
||||
- READMEs and documentation update
|
||||
|
||||
-- Xavier Guimard <x.guimard@free.fr> Tue, 27 Feb 2007 15:01:09 +0100
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ respawn
|
|||
|
||||
pre-start script
|
||||
[ -x /usr/sbin/llng-fastcgi-server ] || { stop; exit 0; }
|
||||
end script
|
||||
end script
|
||||
|
||||
exec mkdir /var/run/llng-fastcgi-server; chown www-data:www-data /var/run/llng-fastcgi-server && /usr/sbin/llng-fastcgi-server -u www-data -g www-data -s /var/run/llng-fastcgi-server/llng-fastcgi.sock -p /var/run/llng-fastcgi-server/llng-fastcgi-server.pid
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ for LLLIB in $LIST; do
|
|||
if [ -f "$SKIPLIST" ]; then
|
||||
grep -v '^ *#' "$SKIPLIST" |grep -v '^ *$' > "$SKIPTMP"
|
||||
fi
|
||||
|
||||
|
||||
for T in $(run-parts --list --regex '(^[a-z0-9.]+$)' ${TESTDIR} | \
|
||||
grep -v -F -f "$SKIPTMP") ; do
|
||||
if echo "$T" | grep -q '\.t$'
|
||||
|
|
|
@ -147,7 +147,7 @@
|
|||
"default" : "accept"
|
||||
},
|
||||
"manager.example.com": {
|
||||
"(?#Configuration)^/(manager\\.html|$)": "$uid eq \"dwho\"",
|
||||
"(?#Configuration)^/(manager\\.html|conf|$)": "$uid eq \"dwho\"",
|
||||
"(?#Notifications)^/notifications": "$uid eq \"dwho\" or $uid eq \"rtyler\"",
|
||||
"(?#Sessions)^/sessions": "$uid eq \"dwho\" or $uid eq \"rtyler\"",
|
||||
"default": "$uid eq \"dwho\" or $uid eq \"rtyler\""
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"_session_kind":"Persistent","_loginHistory":{"successLogin":[{"ipAddr":"127.0.0.1","_utime":1548016089}]},"_2fDevices":"[{\"type\":\"U2F\",\"_keyHandle\":\"CTPeZD3aFrNOY4yVWH4o1MKSn2aLH2OwLOWTtrQSlt_6LtUyki5nzrwBEeuxj7PRSujFZQDaMTfrEb-gr22Qfg\",\"_userKey\":\"BI1MGzKj1C9mMV8PwrYMggQXlItLBNSB19rNnFgUpLMBjAkMW8w3Sqg8s_hUGbdfdWX99duquzIzRLUtRUEvJLo\",\"name\":\"MyU2FKey\",\"epoch\":1548016193},{\"epoch\":1548016213,\"name\":\"MyYubikey\",\"_yubikey\":\"cccccchehfff\",\"type\":\"UBK\"},{\"epoch\":1548018950,\"name\":\"MyU2FKeyBlue\",\"_userKey\":\"BDEa8pQfV9agdvsX63bcwceRTXR_QvDdm5hQ5ZKQUaH4HlOi8ab4fQfl9CIACALWYm0jQcpfaRAcACiSCdwGrnI\",\"_keyHandle\":\"ZD_G6EfDv4FzttWS9RCS80SaSlRTXgtJU9r-1gInsQ4Jj1555r7nnrYhIvRfE4CTyH7NyGrt9fMnMMgByAx97Q\",\"type\":\"U2F\"}]","_session_id":"5efe8af397fc3577e05b483aca964f1b","_session_uid":"dwho","_updateTime":"20190120221550","_utime":1548016089}
|
||||
{"_session_kind":"Persistent","_loginHistory":{"successLogin":[{"ipAddr":"127.0.0.1","_utime":1548016089}]},"_2fDevices":"[]","_session_id":"5efe8af397fc3577e05b483aca964f1b","_session_uid":"dwho","_updateTime":"20190120221550","_utime":1548016089}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"_session_kind":"Persistent","_loginHistory":{"successLogin":[{"ipAddr":"127.0.0.1","_utime":1548016089}]},"_2fDevices":"[{\"type\":\"U2F\",\"_keyHandle\":\"CTPeZD3aFrNOY4yVWH4o1MKSn2aLH2OwLOWTtrQSlt_6LtUyki5nzrwBEeuxj7PRSujFZQDaMTfrEb-gr22Qfg\",\"_userKey\":\"BI1MGzKj1C9mMV8PwrYMggQXlItLBNSB19rNnFgUpLMBjAkMW8w3Sqg8s_hUGbdfdWX99duquzIzRLUtRUEvJLo\",\"name\":\"MyU2FKey\",\"epoch\":1548016193},{\"epoch\":1548016213,\"name\":\"MyYubikey\",\"_yubikey\":\"cccccchehfff\",\"type\":\"UBK\"},{\"epoch\":1548018950,\"name\":\"MyU2FKeyBlue\",\"_userKey\":\"BDEa8pQfV9agdvsX63bcwceRTXR_QvDdm5hQ5ZKQUaH4HlOi8ab4fQfl9CIACALWYm0jQcpfaRAcACiSCdwGrnI\",\"_keyHandle\":\"ZD_G6EfDv4FzttWS9RCS80SaSlRTXgtJU9r-1gInsQ4Jj1555r7nnrYhIvRfE4CTyH7NyGrt9fMnMMgByAx97Q\",\"type\":\"U2F\"}]","_session_id":"5efe8af397fc3577e05b483aca964f1b","_session_uid":"dwho","_updateTime":"20190120221550","_utime":1548016089}
|
|
@ -60,7 +60,7 @@ describe('00 Lemonldap::NG', function() {
|
|||
it('should authenticate with history', function() {
|
||||
expect(browser.driver.findElement(by.css('[trspan="back2Portal"]')).getText()).toEqual('Retourner au portail');
|
||||
browser.driver.findElement(by.css('[trspan="back2Portal"]')).click();
|
||||
|
||||
|
||||
// Failed login attempt
|
||||
browser.driver.findElement(by.xpath("//input[@name='user']")).sendKeys('dwho');
|
||||
browser.driver.findElement(by.xpath("//input[@name='password']")).sendKeys('ohwd');
|
||||
|
@ -68,7 +68,7 @@ describe('00 Lemonldap::NG', function() {
|
|||
browser.driver.findElement(by.xpath("//button[@type='submit']")).click();
|
||||
expect(browser.driver.findElement(by.css('[trmsg="5"]')).getText()).toEqual('Mot de passe ou identifiant incorrect');
|
||||
browser.driver.findElement(by.css('[trspan="goToPortal"]')).click();
|
||||
|
||||
|
||||
// Login attempt
|
||||
browser.driver.findElement(by.xpath("//input[@name='user']")).sendKeys('dwho');
|
||||
browser.driver.findElement(by.xpath("//input[@name='password']")).sendKeys('dwho');
|
||||
|
@ -111,4 +111,4 @@ describe('00 Lemonldap::NG', function() {
|
|||
browser.driver.findElement(by.xpath("//button[@type='submit']")).click();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -64,7 +64,7 @@ describe('10 Lemonldap::NG', function() {
|
|||
expect(links[2].getText()).toEqual('Gestionnaire 2ndFA');
|
||||
expect(links[3].getText()).toEqual('Aller au portail');
|
||||
expect(browser.driver.findElement(by.css('[trspan="yourNewTotpKey"]')).getText()).toEqual('Votre nouvelle clef TOTP. Testez-la et entrez le code');
|
||||
|
||||
|
||||
// Submit an empty form
|
||||
browser.driver.findElement(by.id('verify')).click();
|
||||
expect(browser.driver.findElement(by.css('[trspan="yourNewTotpKey"]')).getText()).toEqual('Remplissez le formulaire');
|
||||
|
|
|
@ -8,7 +8,7 @@ respawn
|
|||
|
||||
pre-start script
|
||||
[ -x /usr/sbin/llng-fastcgi-server ] || { stop; exit 0; }
|
||||
end script
|
||||
end script
|
||||
|
||||
exec mkdir __FASTCGISOCKDIR__; chown __USER__:__GROUP__ __FASTCGISOCKDIR__ && /usr/sbin/llng-fastcgi-server -u __USER__ -g __GROUP__ -s __FASTCGISOCKDIR__/llng-fastcgi.sock -p __FASTCGISOCKDIR__/llng-fastcgi-server.pid
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ our %EXPORT_TAGS = (
|
|||
APPLYSECTION
|
||||
NO
|
||||
$hashParameters
|
||||
@sessionTypes
|
||||
@sessionTypes
|
||||
)
|
||||
]
|
||||
);
|
||||
|
|
|
@ -347,7 +347,7 @@ __DATA__
|
|||
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
||||
</AttributeAuthorityDescriptor>
|
||||
</TMPL_UNLESS>
|
||||
|
||||
|
||||
<Organization>
|
||||
<OrganizationName xml:lang="en"><TMPL_VAR NAME="samlOrganizationName"></OrganizationName>
|
||||
<OrganizationDisplayName xml:lang="en"><TMPL_VAR NAME="samlOrganizationDisplayName"></OrganizationDisplayName>
|
||||
|
|
|
@ -481,7 +481,7 @@ Syslog facility. If empty, STDERR will be used for logging
|
|||
|
||||
L<http://lemonldap-ng.org/>, L<Lemonldap::NG::Portal>, L<Lemonldap::NG::Handler>,
|
||||
L<Plack>, L<PSGI>, L<Lemonldap::NG::Common::PSGI::Router>,
|
||||
L<Lemonldap::NG::Common::PSGI::Request>, L<HTML::Template>,
|
||||
L<Lemonldap::NG::Common::PSGI::Request>, L<HTML::Template>,
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ Example:
|
|||
# Set headers
|
||||
$req->respHeaders( "Location" => "http://x.y.z/", Etag => "XYZ", );
|
||||
# Add header
|
||||
$req->respHeaders->{"X-Key"} = "Value";
|
||||
$req->respHeaders->{"X-Key"} = "Value";
|
||||
|
||||
=head2 set_param( $key, $value )
|
||||
|
||||
|
@ -220,7 +220,7 @@ contains "application/json" or "text/json").
|
|||
|
||||
L<http://lemonldap-ng.org/>, L<Lemonldap::NG::Common::PSGI>,
|
||||
L<Lemonldap::NG::Hander::PSGI>, L<Plack::Request>,
|
||||
L<Lemonldap::NG::Portal::Main::Constants>,
|
||||
L<Lemonldap::NG::Portal::Main::Constants>,
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ sub genRoute {
|
|||
$routes->{$word} = $dest;
|
||||
}
|
||||
else {
|
||||
die "Type $t unauthorizated in routes";
|
||||
die "Type $t unauthorized in routes";
|
||||
}
|
||||
}
|
||||
elsif ( $self->can($dest) ) {
|
||||
|
@ -322,7 +322,7 @@ bookId parameter will be stored in $req->params('bookId');
|
|||
|
||||
$self->addRoute( books => { ':bookId' => { pages => { ':pageId' => 'page' } } }, ['GET'] );
|
||||
|
||||
=item to manage simultaneously the 2 previous examples
|
||||
=item to manage simultaneously the 2 previous examples
|
||||
|
||||
$self->addRoute( books => { ':bookId' => { pages => { ':pageId' => 'page' } } }, ['GET'] )
|
||||
->addRoute( books => { ':bookId' => { '*' => 'book' } }, ['GET'] );
|
||||
|
@ -349,7 +349,7 @@ logLevel, staticPrefix, templateDir, links, syslog).
|
|||
|
||||
L<http://lemonldap-ng.org/>, L<Lemonldap::NG::Portal>, L<Lemonldap::NG::Handler>,
|
||||
L<Plack>, L<PSGI>, L<Lemonldap::NG::Common::PSGI>,
|
||||
L<Lemonldap::NG::Common::PSGI::Request>, L<HTML::Template>,
|
||||
L<Lemonldap::NG::Common::PSGI::Request>, L<HTML::Template>,
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ Returns a list of groups to which user belongs.
|
|||
|
||||
L<http://lemonldap-ng.org/>, L<Lemonldap::NG::Portal>, L<Lemonldap::NG::Handler>,
|
||||
L<Plack>, L<PSGI>, L<Lemonldap::NG::Common::PSGI::Router>,
|
||||
L<Lemonldap::NG::Common::PSGI::Request>, L<HTML::Template>,
|
||||
L<Lemonldap::NG::Common::PSGI::Request>, L<HTML::Template>,
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ Returns a list of groups to which user belongs.
|
|||
|
||||
L<http://lemonldap-ng.org/>, L<Lemonldap::NG::Portal>, L<Lemonldap::NG::Handler>,
|
||||
L<Plack>, L<PSGI>, L<Lemonldap::NG::Common::PSGI::Router>,
|
||||
L<Lemonldap::NG::Common::PSGI::Request>, L<HTML::Template>,
|
||||
L<Lemonldap::NG::Common::PSGI::Request>, L<HTML::Template>,
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
+-> if protected:
|
||||
Handler::PSGI::Base::_authAndTrace()
|
||||
|
||||
|
||||
|
||||
_Common::PSGI::run()_ returns a subroutine
|
||||
|
||||
## HTTP responses
|
||||
|
|
|
@ -88,8 +88,10 @@ sub init {
|
|||
$self->csp(
|
||||
"default-src 'self' $portal;frame-ancestors 'none';form-action 'self';"
|
||||
);
|
||||
$self->brw( $self->{viewerAllowBrowser} || $conf->{viewerAllowBrowser} );
|
||||
$self->dif( $self->{viewerAllowDiff} || $conf->{viewerAllowDiff} );
|
||||
$self->brw( $self->{viewerAllowBrowser}
|
||||
|| $conf->{viewerAllowBrowser}
|
||||
|| 0 );
|
||||
$self->dif( $self->{viewerAllowDiff} || $conf->{viewerAllowDiff} || 0 );
|
||||
$self->defaultRoute( $working[0]->defaultRoute );
|
||||
|
||||
# Find out more glyphicones at https://www.w3schools.com/icons/bootstrap_icons_glyphicons.asp
|
||||
|
@ -143,8 +145,9 @@ sub tplParams {
|
|||
sub javascript {
|
||||
my ($self) = @_;
|
||||
return
|
||||
'var formPrefix=staticPrefix+"forms/";var confPrefix=scriptname+"confs/";var viewPrefix=scriptname+"view/";'
|
||||
. 'var allowDiff=' . $self->dif . ';'
|
||||
'var formPrefix=staticPrefix+"forms/";var confPrefix=scriptname+"confs/";var viewPrefix=scriptname+"view/";'
|
||||
. 'var allowDiff='
|
||||
. $self->dif . ';'
|
||||
. ( $self->links ? 'var links=' . to_json( $self->links ) . ';' : '' )
|
||||
. (
|
||||
$self->menuLinks
|
||||
|
|
|
@ -2486,7 +2486,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
|
|||
},
|
||||
'requireToken' => {
|
||||
'default' => 1,
|
||||
'type' => 'bool'
|
||||
'type' => 'boolOrExpr'
|
||||
},
|
||||
'rest2fActivation' => {
|
||||
'default' => 0,
|
||||
|
|
|
@ -339,7 +339,7 @@ our %EXPORT_TAGS = (
|
|||
APPLYSECTION
|
||||
NO
|
||||
\$hashParameters
|
||||
\@sessionTypes
|
||||
\@sessionTypes
|
||||
)
|
||||
]
|
||||
);
|
||||
|
@ -735,7 +735,7 @@ some words for other developpers
|
|||
if test is not defined for this type or if test must
|
||||
be more restrictive, set here a regular expression or a subroutine. Arguments
|
||||
passed to subroutine are (keyValue, newConf, currentKey). It returns 2
|
||||
arguments: a boolean result and a message (if non empty message will be
|
||||
arguments: a boolean result and a message (if non empty message will be
|
||||
displayed as warning or error depending of result);
|
||||
|
||||
=item msgFail (optional):
|
||||
|
|
|
@ -629,7 +629,7 @@ sub attributes {
|
|||
},
|
||||
requireToken => {
|
||||
default => 1,
|
||||
type => 'bool',
|
||||
type => 'boolOrExpr',
|
||||
documentation => 'Enable token for forms',
|
||||
},
|
||||
tokenUseGlobalStorage => {
|
||||
|
|
|
@ -162,7 +162,7 @@ sub zeroConf {
|
|||
},
|
||||
"manager.$domain" => {
|
||||
'default' => '$uid eq "dwho" or $uid eq "rtyler"',
|
||||
'(?#Configuration)^/(manager\.html|$)' => '$uid eq "dwho"',
|
||||
'(?#Configuration)^/(manager\.html|conf|$)' => '$uid eq "dwho"',
|
||||
'(?#Sessions)/sessions' => '$uid eq "dwho" or $uid eq "rtyler"',
|
||||
'(?#Notifications)/notifications' =>
|
||||
'$uid eq "dwho" or $uid eq "rtyler"',
|
||||
|
|
|
@ -11,7 +11,7 @@ use feature 'state';
|
|||
|
||||
extends 'Lemonldap::NG::Manager::Conf';
|
||||
|
||||
our $VERSION = '2.0.3';
|
||||
our $VERSION = '2.1.0';
|
||||
|
||||
#############################
|
||||
# I. INITIALIZATION METHODS #
|
||||
|
|
|
@ -5241,7 +5241,7 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
|
|||
|
||||
if (tooltip) {
|
||||
tooltip.remove();
|
||||
|
||||
|
||||
tooltip = null;
|
||||
if (adjustmentTimeout) {
|
||||
$timeout.cancel(adjustmentTimeout);
|
||||
|
@ -5249,7 +5249,7 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
|
|||
}
|
||||
|
||||
openedTooltips.remove(ttScope);
|
||||
|
||||
|
||||
if (tooltipLinkedScope) {
|
||||
tooltipLinkedScope.$destroy();
|
||||
tooltipLinkedScope = null;
|
||||
|
@ -7773,4 +7773,4 @@ angular.module('ui.bootstrap.position').run(function() {!angular.$$csp().noInlin
|
|||
angular.module('ui.bootstrap.datepickerPopup').run(function() {!angular.$$csp().noInlineStyle && !angular.$$uibDatepickerpopupCss && angular.element(document).find('head').prepend('<style type="text/css">.uib-datepicker-popup.dropdown-menu{display:block;float:none;margin:0;}.uib-button-bar{padding:10px 9px 2px;}</style>'); angular.$$uibDatepickerpopupCss = true; });
|
||||
angular.module('ui.bootstrap.tooltip').run(function() {!angular.$$csp().noInlineStyle && !angular.$$uibTooltipCss && angular.element(document).find('head').prepend('<style type="text/css">[uib-tooltip-popup].tooltip.top-left > .tooltip-arrow,[uib-tooltip-popup].tooltip.top-right > .tooltip-arrow,[uib-tooltip-popup].tooltip.bottom-left > .tooltip-arrow,[uib-tooltip-popup].tooltip.bottom-right > .tooltip-arrow,[uib-tooltip-popup].tooltip.left-top > .tooltip-arrow,[uib-tooltip-popup].tooltip.left-bottom > .tooltip-arrow,[uib-tooltip-popup].tooltip.right-top > .tooltip-arrow,[uib-tooltip-popup].tooltip.right-bottom > .tooltip-arrow,[uib-tooltip-html-popup].tooltip.top-left > .tooltip-arrow,[uib-tooltip-html-popup].tooltip.top-right > .tooltip-arrow,[uib-tooltip-html-popup].tooltip.bottom-left > .tooltip-arrow,[uib-tooltip-html-popup].tooltip.bottom-right > .tooltip-arrow,[uib-tooltip-html-popup].tooltip.left-top > .tooltip-arrow,[uib-tooltip-html-popup].tooltip.left-bottom > .tooltip-arrow,[uib-tooltip-html-popup].tooltip.right-top > .tooltip-arrow,[uib-tooltip-html-popup].tooltip.right-bottom > .tooltip-arrow,[uib-tooltip-template-popup].tooltip.top-left > .tooltip-arrow,[uib-tooltip-template-popup].tooltip.top-right > .tooltip-arrow,[uib-tooltip-template-popup].tooltip.bottom-left > .tooltip-arrow,[uib-tooltip-template-popup].tooltip.bottom-right > .tooltip-arrow,[uib-tooltip-template-popup].tooltip.left-top > .tooltip-arrow,[uib-tooltip-template-popup].tooltip.left-bottom > .tooltip-arrow,[uib-tooltip-template-popup].tooltip.right-top > .tooltip-arrow,[uib-tooltip-template-popup].tooltip.right-bottom > .tooltip-arrow,[uib-popover-popup].popover.top-left > .arrow,[uib-popover-popup].popover.top-right > .arrow,[uib-popover-popup].popover.bottom-left > .arrow,[uib-popover-popup].popover.bottom-right > .arrow,[uib-popover-popup].popover.left-top > .arrow,[uib-popover-popup].popover.left-bottom > .arrow,[uib-popover-popup].popover.right-top > .arrow,[uib-popover-popup].popover.right-bottom > .arrow,[uib-popover-html-popup].popover.top-left > .arrow,[uib-popover-html-popup].popover.top-right > .arrow,[uib-popover-html-popup].popover.bottom-left > .arrow,[uib-popover-html-popup].popover.bottom-right > .arrow,[uib-popover-html-popup].popover.left-top > .arrow,[uib-popover-html-popup].popover.left-bottom > .arrow,[uib-popover-html-popup].popover.right-top > .arrow,[uib-popover-html-popup].popover.right-bottom > .arrow,[uib-popover-template-popup].popover.top-left > .arrow,[uib-popover-template-popup].popover.top-right > .arrow,[uib-popover-template-popup].popover.bottom-left > .arrow,[uib-popover-template-popup].popover.bottom-right > .arrow,[uib-popover-template-popup].popover.left-top > .arrow,[uib-popover-template-popup].popover.left-bottom > .arrow,[uib-popover-template-popup].popover.right-top > .arrow,[uib-popover-template-popup].popover.right-bottom > .arrow{top:auto;bottom:auto;left:auto;right:auto;margin:0;}[uib-popover-popup].popover,[uib-popover-html-popup].popover,[uib-popover-template-popup].popover{display:block !important;}</style>'); angular.$$uibTooltipCss = true; });
|
||||
angular.module('ui.bootstrap.timepicker').run(function() {!angular.$$csp().noInlineStyle && !angular.$$uibTimepickerCss && angular.element(document).find('head').prepend('<style type="text/css">.uib-time input{width:50px;}</style>'); angular.$$uibTimepickerCss = true; });
|
||||
angular.module('ui.bootstrap.typeahead').run(function() {!angular.$$csp().noInlineStyle && !angular.$$uibTypeaheadCss && angular.element(document).find('head').prepend('<style type="text/css">[uib-typeahead-popup].dropdown-menu{display:block;}</style>'); angular.$$uibTypeaheadCss = true; });
|
||||
angular.module('ui.bootstrap.typeahead').run(function() {!angular.$$csp().noInlineStyle && !angular.$$uibTypeaheadCss && angular.element(document).find('head').prepend('<style type="text/css">[uib-typeahead-popup].dropdown-menu{display:block;}</style>'); angular.$$uibTypeaheadCss = true; });
|
||||
|
|
|
@ -383,12 +383,12 @@
|
|||
if (element.prop('tagName').toLowerCase() === 'table') {
|
||||
scope.$emptyElm = angular.element($window.document.createElement('tr'));
|
||||
$trElm = element.find('tr');
|
||||
|
||||
|
||||
//If we can find a tr, then we can use its td children as the empty element colspan.
|
||||
if ($trElm.length > 0) {
|
||||
emptyElmColspan = angular.element($trElm).children().length;
|
||||
} else {
|
||||
|
||||
|
||||
//If not, by setting a huge colspan we make sure it takes full width.
|
||||
//TODO(jcarter): Check for negative side effects.
|
||||
emptyElmColspan = 1000000;
|
||||
|
@ -1512,7 +1512,7 @@
|
|||
|
||||
/**
|
||||
* Get the event object for touches.
|
||||
*
|
||||
*
|
||||
* @param {MouseEvent|TouchEvent} e MouseEvent or TouchEvent that kicked off dragX method.
|
||||
* @return {MouseEvent|TouchEvent} Object returned as original event object.
|
||||
*/
|
||||
|
@ -1530,7 +1530,7 @@
|
|||
|
||||
/**
|
||||
* Generate object used to store data about node being moved.
|
||||
*
|
||||
*
|
||||
* {angular.$scope} node Scope of the node that is being moved.
|
||||
*/
|
||||
dragInfo: function (node) {
|
||||
|
@ -1760,19 +1760,19 @@
|
|||
pos.nowX = pageX;
|
||||
pos.nowY = pageY;
|
||||
|
||||
//Distance mouse moved between events.
|
||||
//Distance mouse moved between events.
|
||||
pos.distX = pos.nowX - pos.lastX;
|
||||
pos.distY = pos.nowY - pos.lastY;
|
||||
|
||||
//Direction mouse was moving.
|
||||
//Direction mouse was moving.
|
||||
pos.lastDirX = pos.dirX;
|
||||
pos.lastDirY = pos.dirY;
|
||||
|
||||
//Direction mouse is now moving (on both axis).
|
||||
//Direction mouse is now moving (on both axis).
|
||||
pos.dirX = pos.distX === 0 ? 0 : pos.distX > 0 ? 1 : -1;
|
||||
pos.dirY = pos.distY === 0 ? 0 : pos.distY > 0 ? 1 : -1;
|
||||
|
||||
//Axis mouse is now moving on.
|
||||
//Axis mouse is now moving on.
|
||||
newAx = Math.abs(pos.distX) > Math.abs(pos.distY) ? 1 : 0;
|
||||
|
||||
//Do nothing on first move.
|
||||
|
@ -1782,7 +1782,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
//Calc distance moved on this axis (and direction).
|
||||
//Calc distance moved on this axis (and direction).
|
||||
if (pos.dirAx !== newAx) {
|
||||
pos.distAxX = 0;
|
||||
pos.distAxY = 0;
|
||||
|
@ -1853,4 +1853,4 @@
|
|||
return res;
|
||||
}
|
||||
|
||||
})();
|
||||
})();
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<span ng-if="!currentCfg.next" trspan="currentConfiguration"></span>
|
||||
<span ng-if="currentCfg.next" trspan="loadedConfiguration"></span>
|
||||
<i ng-if="currentCfg.prev">(<a trspan="diffWithPrevious" target="_blank" href="{{scriptname}}/diff.html#!/{{currentCfg.cfgNum}}" role="link"></a>)</i>
|
||||
|
||||
|
||||
</h3>
|
||||
</TMPL_IF>
|
||||
</div>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<span ng-if="!currentCfg.next" trspan="currentConfiguration"></span>
|
||||
<span ng-if="currentCfg.next" trspan="loadedConfiguration"></span>
|
||||
<i ng-if="currentCfg.prev && allowDiff">(<a trspan="diffWithPrevious" target="_blank" href="{{scriptname}}/viewDiff.html#!/{{currentCfg.cfgNum}}" role="link"></a>)</i>
|
||||
|
||||
|
||||
</h3>
|
||||
</div>
|
||||
<table class="table table-striped">
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -37,10 +37,10 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Tree -->
|
||||
|
||||
|
||||
<div class="text-center"><p class="badge">{{total}} <span trspan="session_s"></span></p></div>
|
||||
<div class="region region-sidebar-first">
|
||||
<section id="block-superfish-1" class="block block-superfish clearfix">
|
||||
|
@ -58,7 +58,7 @@
|
|||
</aside>
|
||||
|
||||
<!-- Right(main) div -->
|
||||
<div id="right" class="col-lg-8 col-md-8 col-sm-7 col-xs-12 scrollable" ng-class="{'hidden-xs':showT&&!showM}">
|
||||
<div id="right" class="col-lg-8 col-md-8 col-sm-7 col-xs-12 scrollable" ng-class="{'hidden-xs':showT&&!showM}">
|
||||
<div class="panel panel-default" ng-hide="currentSession===null">
|
||||
<div class="panel-heading">
|
||||
<h1 class="panel-title text-center">{{translate("sessionTitle")}} {{currentSession.id}}</h1>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<div class="navbar-collapse" ng-class="{'collapse':!showM}" id="formmenu">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a class="link" ng-click="home()"><i class="glyphicon glyphicon-home"></i></a></li>
|
||||
|
||||
|
||||
<TMPL_IF NAME="ALLOWBROWSER">
|
||||
<li uib-dropdown>
|
||||
<a id="navmenu" name="menu" uib-dropdown-toggle data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="glyphicon glyphicon-cog"></i> {{translate('browse')}} <span class="caret"></span></a>
|
||||
|
@ -45,7 +45,7 @@
|
|||
</li>
|
||||
<li>
|
||||
<i class="glyphicon glyphicon-lock"></i>
|
||||
<u>{{translate('readOnlyMode')}}</u>
|
||||
<u>{{translate('readOnlyMode')}}</u>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -58,7 +58,7 @@
|
|||
<div class="panel-body">
|
||||
<iframe id="helpframe" width="100%" height="100%" ng-src="{{translate('/doc/')+'pages/documentation/current/'+helpUrl}}" frameborder="0"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -143,6 +143,7 @@ MANIFEST This list of files
|
|||
META.json
|
||||
META.yml
|
||||
README
|
||||
scripts/llngDeleteSession
|
||||
site/coffee/2fregistration.coffee
|
||||
site/coffee/autoRenew.coffee
|
||||
site/coffee/confirm.coffee
|
||||
|
|
|
@ -61,6 +61,9 @@ sub authenticate {
|
|||
"Unable to refresh entry for " . $self->p->{user} );
|
||||
}
|
||||
|
||||
$req->data->{noerror} = 1;
|
||||
$self->setSecurity($req);
|
||||
|
||||
# Security: never create session here
|
||||
return $res || PE_DONE;
|
||||
}
|
||||
|
|
|
@ -34,16 +34,31 @@ has authnLevel => (
|
|||
|
||||
has captcha => ( is => 'rw' );
|
||||
has ott => ( is => 'rw' );
|
||||
has ottRule => ( is => 'rw', default => sub { 1 } );
|
||||
|
||||
# INITIALIZATION
|
||||
|
||||
sub init {
|
||||
if ( $_[0]->{conf}->{captcha_login_enabled} ) {
|
||||
$_[0]->captcha( $_[0]->p->loadModule('::Lib::Captcha') ) or return 0;
|
||||
my ($self) = @_;
|
||||
my $hd = $self->p->HANDLER;
|
||||
|
||||
# Parse OTT activation rule
|
||||
$self->logger->debug(
|
||||
"OTT activation rule -> " . $self->conf->{requireToken} );
|
||||
my $rule =
|
||||
$hd->buildSub( $hd->substitute( $self->conf->{requireToken} ) );
|
||||
unless ($rule) {
|
||||
$self->error( "Bad OTT activation rule -> " . $hd->tsv->{jail}->error );
|
||||
return 0;
|
||||
}
|
||||
elsif ( $_[0]->{conf}->{requireToken} ) {
|
||||
$_[0]->ott( $_[0]->p->loadModule('::Lib::OneTimeToken') ) or return 0;
|
||||
$_[0]->ott->timeout( $_[0]->conf->{formTimeout} );
|
||||
$self->{ottRule} = $rule;
|
||||
|
||||
if ( $self->{conf}->{captcha_login_enabled} ) {
|
||||
$self->captcha( $self->p->loadModule('::Lib::Captcha') ) or return 0;
|
||||
}
|
||||
else {
|
||||
$self->ott( $self->p->loadModule('::Lib::OneTimeToken') ) or return 0;
|
||||
$self->ott->timeout( $self->conf->{formTimeout} );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -96,13 +111,14 @@ sub extractFormInfo {
|
|||
}
|
||||
|
||||
# Security: check for captcha or token
|
||||
if ( $self->captcha or $self->ott ) {
|
||||
if ( $self->captcha or $self->ottRule->( $req, $req->env ) ) {
|
||||
my $token;
|
||||
unless ( $token = $req->param('token') ) {
|
||||
$self->userLogger->error('Authentication tried without token');
|
||||
$self->ott->setToken($req);
|
||||
return PE_NOTOKEN;
|
||||
}
|
||||
|
||||
if ( $self->captcha ) {
|
||||
my $code = $req->param('captcha');
|
||||
unless ($code) {
|
||||
|
@ -117,7 +133,7 @@ sub extractFormInfo {
|
|||
}
|
||||
$self->logger->debug("Captcha code verified");
|
||||
}
|
||||
elsif ( $self->ott ) {
|
||||
elsif ( $self->ottRule->( $req, $req->env ) ) {
|
||||
unless ( $req->data->{tokenVerified}
|
||||
or $self->ott->getToken($token) )
|
||||
{
|
||||
|
@ -169,7 +185,7 @@ sub setSecurity {
|
|||
}
|
||||
|
||||
# Else get token
|
||||
elsif ( $self->ott ) {
|
||||
elsif ( $self->ottRule->( $req, $req->env ) ) {
|
||||
$self->ott->setToken($req);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -363,7 +363,7 @@ sub logout {
|
|||
my $session_id = $req->{sessionInfo}->{_session_id} || $req->{id};
|
||||
|
||||
# Delete linked CAS sessions
|
||||
$self->deleteCasSecondarySessions($session_id);
|
||||
$self->deleteCasSecondarySessions($session_id) if ($session_id);
|
||||
|
||||
return PE_OK;
|
||||
}
|
||||
|
|
|
@ -198,8 +198,8 @@ sub run {
|
|||
"Override $_ OIDC param by value present in request parameter"
|
||||
);
|
||||
$oidc_request->{$_} = $request->{$_};
|
||||
$self->p->setHiddenFormValue( $req, $_, $request->{$_},
|
||||
'' );
|
||||
$self->p->setHiddenFormValue( $req, $_, $request->{$_}, '',
|
||||
0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -855,7 +855,8 @@ sub run {
|
|||
$self->logger->debug( "OIDC request parameter $param: "
|
||||
. $oidc_request->{$param} );
|
||||
$self->p->setHiddenFormValue( $req, $param,
|
||||
$oidc_request->{$param}, '' );
|
||||
$oidc_request->{$param},
|
||||
'', 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -585,7 +585,7 @@ sub run {
|
|||
$self->logger->debug(
|
||||
"NameID Content is " . $login->nameIdentifier->content );
|
||||
|
||||
# Push mandatory attributes
|
||||
# Push attributes
|
||||
my @attributes;
|
||||
|
||||
foreach (
|
||||
|
@ -605,20 +605,21 @@ sub run {
|
|||
# Name is required
|
||||
next unless $name;
|
||||
|
||||
# Do not send attribute if not mandatory
|
||||
unless ($mandatory) {
|
||||
$self->logger->debug(
|
||||
"SAML2 attribute $name is not mandatory");
|
||||
next;
|
||||
}
|
||||
|
||||
# Error if corresponding attribute is not in user session
|
||||
my $value = $req->{sessionInfo}->{$_};
|
||||
unless ( defined $value ) {
|
||||
$self->logger->warn(
|
||||
"Session key $_ is required to set SAML $name attribute"
|
||||
);
|
||||
return PE_SAML_SSO_ERROR;
|
||||
if ($mandatory) {
|
||||
$self->logger->error(
|
||||
"Session key $_ is required to set SAML $name attribute"
|
||||
);
|
||||
return PE_SAML_SSO_ERROR;
|
||||
}
|
||||
else {
|
||||
$self->logger->debug(
|
||||
"SAML2 attribute $name has no value but is not mandatory, skip it"
|
||||
);
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
$self->logger->debug(
|
||||
|
@ -1738,13 +1739,77 @@ sub sloServer {
|
|||
|
||||
elsif ($response) {
|
||||
|
||||
# No SLO response should be here
|
||||
# else it means SSO session was not closed: launching it
|
||||
$self->logger->debug(
|
||||
"SLO response found on an active SSO session, ignoring it");
|
||||
$req->data->{samlSLOCalled} = 1;
|
||||
return $self->p->do( $req,
|
||||
[ @{ $self->p->beforeLogout }, 'deleteSession' ] );
|
||||
# Process logout response
|
||||
my $result = $self->processLogoutResponseMsg( $logout, $response );
|
||||
|
||||
unless ($result) {
|
||||
$self->logger->error("Fail to process logout response");
|
||||
$self->imgnok($req);
|
||||
}
|
||||
|
||||
$self->logger->debug("Logout response is valid");
|
||||
|
||||
# Check Destination
|
||||
$self->imgnok($req)
|
||||
unless ( $self->checkDestination( $logout->response, $url ) );
|
||||
|
||||
# Get SP entityID
|
||||
my $sp = $logout->remote_providerID();
|
||||
|
||||
$self->logger->debug("Found entityID $sp in SAML message");
|
||||
|
||||
# SP conf key
|
||||
my $spConfKey = $self->spList->{$sp}->{confKey};
|
||||
|
||||
unless ($spConfKey) {
|
||||
$self->logger->error("$sp do not match any SP in configuration");
|
||||
$self->imgnok($req);
|
||||
}
|
||||
|
||||
$self->logger->debug("$sp match $spConfKey SP in configuration");
|
||||
|
||||
# Do we check signature?
|
||||
my $checkSLOMessageSignature =
|
||||
$self->conf->{samlSPMetaDataOptions}->{$spConfKey}
|
||||
->{samlSPMetaDataOptionsCheckSLOMessageSignature};
|
||||
|
||||
if ($checkSLOMessageSignature) {
|
||||
unless ( $self->checkSignatureStatus($logout) ) {
|
||||
$self->logger->error("Signature is not valid");
|
||||
$self->imgnok($req);
|
||||
}
|
||||
else {
|
||||
$self->logger->debug("Signature is valid");
|
||||
}
|
||||
}
|
||||
else {
|
||||
$self->logger->debug("Message signature will not be checked");
|
||||
}
|
||||
|
||||
# Store success status for this SLO request
|
||||
if ($relaystate) {
|
||||
my $sloStatusSessionInfos = $self->getSamlSession($relaystate);
|
||||
|
||||
if ($sloStatusSessionInfos) {
|
||||
$sloStatusSessionInfos->update( { $spConfKey => 1 } );
|
||||
$self->logger->debug(
|
||||
"Store SLO status for $spConfKey in session $relaystate");
|
||||
}
|
||||
else {
|
||||
$self->logger->warn(
|
||||
"Unable to store SLO status for $spConfKey in session $relaystate"
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$self->logger->warn(
|
||||
"Unable to store SLO status for $spConfKey because there is no RelayState"
|
||||
);
|
||||
}
|
||||
|
||||
# SLO response is OK
|
||||
$self->logger->debug("Display OK status for SLO on $spConfKey");
|
||||
$self->imgok($req);
|
||||
}
|
||||
|
||||
else {
|
||||
|
|
|
@ -2385,21 +2385,12 @@ sub samldate2timestamp {
|
|||
sub sendLogoutResponseToServiceProvider {
|
||||
my ( $self, $req, $logout, $method ) = @_;
|
||||
|
||||
my $httpmethod = $self->getFirstHttpMethod(
|
||||
$self->lassoServer,
|
||||
$logout->remote_providerID,
|
||||
Lasso::Constants::MD_PROTOCOL_TYPE_SINGLE_LOGOUT
|
||||
);
|
||||
if ( $httpmethod == Lasso::Constants::HTTP_METHOD_NONE ) {
|
||||
$self->logger->warn( "Provider "
|
||||
. $logout->remote_providerID
|
||||
. " has no SingleLogoutService in metadata, staying on portal" );
|
||||
return $self->p->do( $req, [] );
|
||||
}
|
||||
|
||||
# Logout response
|
||||
unless ( $self->buildLogoutResponseMsg($logout) ) {
|
||||
return $self->p->sendError( $req, "Unable to build SLO response", 500 );
|
||||
$self->logger->warn( "Could not build a logout response for provider "
|
||||
. $logout->remote_providerID
|
||||
. ", staying on portal" );
|
||||
return $self->p->do( $req, [] );
|
||||
}
|
||||
|
||||
# Send response depending on request method
|
||||
|
@ -3432,8 +3423,8 @@ Send logout request to a provider
|
|||
|
||||
Send logout response issue from a logout request to all other
|
||||
providers. If information have to be displayed to users, such as
|
||||
iframe to send HTTP-Redirect or HTTP-POST logout request, then
|
||||
$self->{_info} will be updated.
|
||||
iframe to send HTTP-Redirect or HTTP-POST logout request, then
|
||||
$self->{_info} will be updated.
|
||||
|
||||
=head2 checkSignatureStatus
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ package Lemonldap::NG::Portal::Main::Plugin;
|
|||
use strict;
|
||||
use Mouse;
|
||||
use HTML::Template;
|
||||
use Data::Dumper;
|
||||
|
||||
our $VERSION = '2.1.0';
|
||||
|
||||
|
|
|
@ -636,7 +636,7 @@ sub setHiddenFormValue {
|
|||
if ( defined $val or !( $val & ~$val ) ) {
|
||||
$key = $prefix . $key;
|
||||
|
||||
#$val =~ s/\+/%2B/g;
|
||||
$val = encode_base64($val) if $base64;
|
||||
$req->{portalHiddenFormValues}->{$key} = $val;
|
||||
$self->logger->debug("Store $val in hidden key $key");
|
||||
}
|
||||
|
@ -917,7 +917,6 @@ sub tplParams {
|
|||
SKIN => $self->getSkin($req),
|
||||
PORTAL_URL => $self->conf->{portal},
|
||||
SKIN_PATH => $portalPath . "skins",
|
||||
ANTIFRAME => $self->conf->{portalAntiFrame},
|
||||
SKIN_BG => $self->conf->{portalSkinBackground},
|
||||
( $self->customParameters ? ( %{ $self->customParameters } ) : () ),
|
||||
%templateParams
|
||||
|
|
|
@ -158,7 +158,7 @@ L<Lemonldap::NG::Portal> second factor plugins.
|
|||
# If self registration is enabled and "activation" is set to "enabled",
|
||||
# replace the rule to detect if user has registered a device key.
|
||||
# The rule must be like this :
|
||||
# By example :
|
||||
# By example :
|
||||
$self->conf->{u2fActivation} = '$_2fDevices =~ /"type":\s*"U2F"/s'
|
||||
# Optionally, the rule can be : '$_2fDevices and $_2fDevices =~ /"type":\s*"U2F"/s'
|
||||
# to avoid warning due to undef variable
|
||||
|
|
|
@ -9,7 +9,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_MALFORMEDUSER
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.3';
|
||||
our $VERSION = '2.1.0';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
||||
|
||||
|
@ -165,8 +165,10 @@ sub check {
|
|||
# Check if user is allowed to access submitted URL and compute headers
|
||||
if ( $url and %$attrs ) {
|
||||
|
||||
# Check url format
|
||||
$url = $self->_urlFormat($url);
|
||||
|
||||
# User is allowed ?
|
||||
$url = 'http://' . $url unless ( $url =~ m#^https?://[^/]*.*# );
|
||||
$auth = $self->_authorization( $req, $url );
|
||||
$self->logger->debug(
|
||||
"checkUser requested for user: $req->{user} and URL: $url");
|
||||
|
@ -276,6 +278,19 @@ sub display {
|
|||
return $self->p->sendHtml( $req, 'checkuser', params => $params, );
|
||||
}
|
||||
|
||||
sub _urlFormat {
|
||||
my ( $self, $url ) = @_;
|
||||
|
||||
$url = 'http://' . $url unless ( $url =~ m#^https?://[^/]*.*# );
|
||||
my ( $proto, $vhost, $appuri ) = $url =~ m#^(https?://)([^/]*)(.*)#;
|
||||
my ( $port ) = $vhost =~ m#^.+(:\d+)$#;
|
||||
$port ||= '';
|
||||
$vhost =~ s/:\d+$//;
|
||||
$vhost .= $self->conf->{domain} unless ( $vhost =~ /\./ );
|
||||
$appuri ||= '/';
|
||||
return "$proto$vhost$port$appuri";
|
||||
}
|
||||
|
||||
sub _userDatas {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
|
@ -313,9 +328,8 @@ sub _authorization {
|
|||
my ( $self, $req, $uri ) = @_;
|
||||
my ( $vhost, $appuri ) = $uri =~ m#^https?://([^/]*)(.*)#;
|
||||
my $exist = 0;
|
||||
$vhost =~ s/:\d+$//;
|
||||
$appuri ||= '/';
|
||||
|
||||
$vhost =~ s/:\d+$//;
|
||||
foreach my $vh ( keys %{ $self->conf->{locationRules} } ) {
|
||||
if ( $vh eq $vhost ) {
|
||||
$exist = 1;
|
||||
|
@ -333,7 +347,8 @@ sub _authorization {
|
|||
|
||||
sub _headers {
|
||||
my ( $self, $req, $uri ) = @_;
|
||||
my ( $vhost, $appuri ) = $uri =~ m#^https?://([^/]*)(.*)#;
|
||||
my ( $vhost ) = $uri =~ m#^https?://([^/]*).*#;
|
||||
|
||||
$vhost =~ s/:\d+$//;
|
||||
$req->{env}->{HTTP_HOST} = $vhost;
|
||||
$self->p->HANDLER->headersInit( $self->{conf} );
|
||||
|
|
|
@ -5,7 +5,7 @@ use Mouse;
|
|||
use Lemonldap::NG::Portal::Main::Constants
|
||||
qw( PE_OK PE_BADCREDENTIALS PE_IMPERSONATION_SERVICE_NOT_ALLOWED PE_MALFORMEDUSER );
|
||||
|
||||
our $VERSION = '2.0.3';
|
||||
our $VERSION = '2.1.0';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ sub confirm {
|
|||
$self->p->setHiddenFormValue(
|
||||
$req,
|
||||
upgrading => $self->ott->createToken,
|
||||
''
|
||||
'', 0
|
||||
); # Insert token
|
||||
return $self->p->login($req);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
#!/usr/bin/perl
|
||||
#=============================================================================
|
||||
# Cleaner for LemonLDAP::NG: removes old sessions from Apache::Session
|
||||
#
|
||||
# This module is written to be used by cron to clean old sessions from
|
||||
# Apache::Session. It does not works with Apache::Session::Memcached
|
||||
#
|
||||
# This is part of LemonLDAP::NG product, released under GPL
|
||||
#=============================================================================
|
||||
|
||||
use Lemonldap::NG::Common::Conf;
|
||||
use Lemonldap::NG::Common::Conf::Constants;
|
||||
use Lemonldap::NG::Common::Apache::Session;
|
||||
use Lemonldap::NG::Common::Session;
|
||||
use strict;
|
||||
use Getopt::Std;
|
||||
|
||||
# Options
|
||||
# -d: debug mode
|
||||
# -f: force delete of corrupted sessions
|
||||
our $opt_d;
|
||||
our $opt_f;
|
||||
getopts('df');
|
||||
|
||||
my $debug = $opt_d;
|
||||
my $force = $opt_f;
|
||||
my $nb_purged = 0;
|
||||
my $nb_error = 0;
|
||||
|
||||
unless (@ARGV) {
|
||||
print STDERR "Usage: $0 <uid>\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
#=============================================================================
|
||||
# Load configuration
|
||||
#=============================================================================
|
||||
my $lmconf = Lemonldap::NG::Common::Conf->new()
|
||||
or die $Lemonldap::NG::Common::Conf::msg;
|
||||
my $conf = $lmconf->getConf or die "Unable to get configuration ($!)";
|
||||
my $localconf = $lmconf->getLocalConf(PORTALSECTION)
|
||||
or die "Unable to get local configuration ($!)";
|
||||
|
||||
if ($localconf) {
|
||||
$conf->{$_} = $localconf->{$_} foreach ( keys %$localconf );
|
||||
}
|
||||
|
||||
print "Configuration loaded\n" if $debug;
|
||||
|
||||
#=============================================================================
|
||||
# Timeout
|
||||
#=============================================================================
|
||||
print "Timeout value: " . $conf->{timeout} . "\n" if $debug;
|
||||
|
||||
#=============================================================================
|
||||
# Apache::Session backends
|
||||
#=============================================================================
|
||||
my @backends;
|
||||
my $module;
|
||||
|
||||
# Sessions
|
||||
if ( defined $conf->{globalStorage} ) {
|
||||
|
||||
# Load module
|
||||
$module = $conf->{globalStorage};
|
||||
eval "use $module";
|
||||
die $@ if ($@);
|
||||
$conf->{globalStorageOptions}->{backend} = $module;
|
||||
|
||||
# Add module in managed backends
|
||||
push @backends, $conf->{globalStorageOptions};
|
||||
|
||||
print "Session backend $module will be used\n" if $debug;
|
||||
}
|
||||
else {
|
||||
print STDERR "Unable to find 'globalStorage' configuration key, aborting\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
#=============================================================================
|
||||
# Load and purge sessions
|
||||
#=============================================================================
|
||||
for my $options (@backends) {
|
||||
|
||||
next if ( $options->{backend} eq "Apache::Session::Memcached" );
|
||||
|
||||
# Get all expired sessions
|
||||
foreach my $reSession (@ARGV) {
|
||||
my $sessions =
|
||||
Lemonldap::NG::Common::Apache::Session->searchOnExpr( $options,
|
||||
$conf->{whatToTrace}, $reSession );
|
||||
|
||||
foreach my $id ( keys %$sessions ) {
|
||||
my $session = Lemonldap::NG::Common::Session->new(
|
||||
storageModule => $options->{backend},
|
||||
storageModuleOptions => $options,
|
||||
cacheModule => $conf->{localSessionStorage},
|
||||
cacheModuleOptions => $conf->{localSessionStorageOptions},
|
||||
id => $id,
|
||||
);
|
||||
|
||||
unless ( $session->data ) {
|
||||
print "Error while opening session $id\n" if $debug;
|
||||
print STDERR "Error on session $id\n";
|
||||
$nb_error++;
|
||||
next;
|
||||
}
|
||||
|
||||
unless ( $session->remove ) {
|
||||
print "Error while deleting session $id\n" if $debug;
|
||||
print STDERR "Error on session $id\n";
|
||||
$nb_error++;
|
||||
next;
|
||||
}
|
||||
print "Session $id has been purged\n" if $debug;
|
||||
$nb_purged++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#=============================================================================
|
||||
# Exit
|
||||
#=============================================================================
|
||||
print "$nb_purged sessions have been purged\n" if $debug;
|
||||
print STDERR
|
||||
"$nb_error sessions remaining, try to purge them with force (option -f)\n"
|
||||
if $nb_error;
|
||||
|
||||
my $exit = $nb_error ? 1 : $nb_purged ? 0 : 1;
|
||||
exit $exit;
|
|
@ -228,8 +228,6 @@ $(document).ready ->
|
|||
datas = getValues()
|
||||
# Export datas for other scripts
|
||||
window.datas = datas
|
||||
if datas['antiframe'] and top != self
|
||||
top.location.href = location.href
|
||||
|
||||
$("#appslist").sortable
|
||||
axis: "y"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Generated by CoffeeScript 1.12.8
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
LemonLDAP::NG Portal jQuery scripts
|
||||
|
@ -226,9 +226,6 @@ LemonLDAP::NG Portal jQuery scripts
|
|||
var action, al, authMenuTabs, back_url, i, l, lang, langdiv, langs, langs2, len, len1, len2, len3, link, m, menuIndex, menuTabs, method, n, nl, nlangs, re, ref, ref1, ref2;
|
||||
datas = getValues();
|
||||
window.datas = datas;
|
||||
if (datas['antiframe'] && top !== self) {
|
||||
top.location.href = location.href;
|
||||
}
|
||||
$("#appslist").sortable({
|
||||
axis: "y",
|
||||
cursor: "move",
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -63,7 +63,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</TMPL_IF>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -61,11 +61,11 @@
|
|||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">common/js/idpchoice.min.js"></script>
|
||||
//else -->
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">common/js/idpchoice.js"></script>
|
||||
<!-- //endif -->
|
||||
<!-- //endif -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<TMPL_IF NAME="PORTAL_URL">
|
||||
<div id="logout">
|
||||
<div class="buttons">
|
||||
|
@ -76,7 +76,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</TMPL_IF>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<span class="fa fa-envelope-open"></span>
|
||||
<span trspan="sendPwd">Send me a link</span>
|
||||
</button>
|
||||
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -123,7 +123,7 @@
|
|||
<TMPL_ELSE>
|
||||
<div class="col-12">
|
||||
</TMPL_IF>
|
||||
|
||||
|
||||
<!-- Name and link (mandatory) -->
|
||||
<h5 class="appname <TMPL_VAR NAME="appid"> card-title">
|
||||
<TMPL_VAR NAME="appname">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<TMPL_INCLUDE NAME="header.tpl">
|
||||
|
||||
<div id="notifcontent" class="container">
|
||||
|
||||
|
||||
<form action="/notifback" method="post" class="notif" role="form">
|
||||
<TMPL_VAR NAME="HIDDEN_INPUTS">
|
||||
<TMPL_IF NAME="CHOICE_VALUE">
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
<div class="buttons">
|
||||
<a href="<TMPL_VAR NAME="PORTAL_URL">2fregisters" class="btn btn-info" role="button">
|
||||
<span class="fa fa-shield"></span>
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<span class="fa fa-shield"></span>
|
||||
<span trspan="sfaManager">sfaManager</span>
|
||||
</a>
|
||||
|
||||
|
||||
<a id="goback" href="<TMPL_VAR NAME="PORTAL_URL">?cancel=1<TMPL_IF NAME="AUTH_URL">&url=<TMPL_VAR NAME="AUTH_URL"></TMPL_IF>" class="btn btn-primary" role="button">
|
||||
<span class="fa fa-home"></span>
|
||||
<span trspan="goToPortal">Go to portal</span>
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<span class="fa fa-shield"></span>
|
||||
<span trspan="sfaManager">sfaManager</span>
|
||||
</a>
|
||||
|
||||
|
||||
<a id="goback" href="<TMPL_VAR NAME="PORTAL_URL">?cancel=1<TMPL_IF NAME="AUTH_URL">&url=<TMPL_VAR NAME="AUTH_URL"></TMPL_IF>" class="btn btn-primary" role="button">
|
||||
<span class="fa fa-home"></span>
|
||||
<span trspan="goToPortal">Go to portal</span>
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
"choicetab":"<TMPL_VAR NAME="CHOICE_VALUE">",
|
||||
"login":"<TMPL_VAR NAME="LOGIN">",
|
||||
"newwindow":<TMPL_VAR NAME="NEWWINDOW" DEFAULT="0">,
|
||||
"antiframe":<TMPL_VAR NAME="ANTIFRAME" DEFAULT="1">,
|
||||
"appslistorder":"<TMPL_VAR NAME="APPSLIST_ORDER">",
|
||||
"scriptname":"<TMPL_VAR NAME="SCRIPT_NAME">",
|
||||
"activeTimer":<TMPL_VAR NAME="ACTIVE_TIMER" DEFAULT="0">,
|
||||
|
|
|
@ -141,7 +141,7 @@ m#iframe src="http://auth.sp.com(/saml/proxySingleLogout)\?(SAMLRequest=.*?)"#,
|
|||
switch ('issuer');
|
||||
ok( $res = $issuer->_get( $url, query => $query, accept => 'text/html' ),
|
||||
'Push SAML response to IdP' );
|
||||
expectOK($res);
|
||||
expectRedirection($res, 'http://auth.idp.com/static/common/icons/ok.png');
|
||||
ok( getHeader( $res, 'Content-Security-Policy' ) !~ /frame-ancestors/,
|
||||
' Frame can be embedded' )
|
||||
or explain( $res->[1],
|
||||
|
|
|
@ -0,0 +1,793 @@
|
|||
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 = 23;
|
||||
my $debug = 'error';
|
||||
my ( $issuer, $sp, $sp2, $res );
|
||||
my %handlerOR = ( issuer => [], sp => [], sp2 => [] );
|
||||
|
||||
# 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
|
||||
ok( $issuer = issuer(), 'Issuer portal' );
|
||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||
switch ('sp');
|
||||
&Lemonldap::NG::Handler::Main::cfgNum( 0, 0 );
|
||||
|
||||
ok( $sp = sp(), 'SP portal' );
|
||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||
|
||||
ok( $sp2 = sp2(), 'SP2 portal' );
|
||||
$handlerOR{sp2} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||
|
||||
# Simple SP access
|
||||
my $res;
|
||||
ok(
|
||||
$res = $sp->_get(
|
||||
'/',
|
||||
accept => 'text/html',
|
||||
query => 'url=aHR0cDovL3Rlc3QxLmV4YW1wbGUuY29tLw=='
|
||||
),
|
||||
'Unauth SP request'
|
||||
);
|
||||
my ( $host, $url, $query );
|
||||
ok(
|
||||
expectCookie( $res, 'lemonldapidp' ) eq
|
||||
'http://auth.idp.com/saml/metadata',
|
||||
'IDP cookie defined'
|
||||
)
|
||||
or explain(
|
||||
$res->[1],
|
||||
'Set-Cookie => lemonldapidp=http://auth.idp.com/saml/metadata; domain=.sp.com; path=/'
|
||||
);
|
||||
( $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/^.*?<form.*?>//s;
|
||||
$body =~ s#</form>.*$##s;
|
||||
my %fields =
|
||||
( $body =~ /<input type="hidden".+?name="(.+?)".+?value="(.*?)"/sg );
|
||||
$fields{user} = $fields{password} = 'french';
|
||||
use URI::Escape;
|
||||
$query =
|
||||
join( '&', map { "$_=" . uri_escape( $fields{$_} ) } keys %fields );
|
||||
ok(
|
||||
$res = $issuer->_post(
|
||||
$url,
|
||||
IO::String->new($query),
|
||||
accept => 'text/html',
|
||||
cookie => $pdata,
|
||||
length => length($query),
|
||||
),
|
||||
'Post authentication'
|
||||
);
|
||||
expectOK($res);
|
||||
my $idpId = expectCookie($res);
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $res, 'auth.sp.com', '/saml/proxySingleSignOnPost',
|
||||
'SAMLResponse', 'RelayState' );
|
||||
|
||||
# Post SAML response to SP
|
||||
switch ('sp');
|
||||
ok(
|
||||
$res = $sp->_post(
|
||||
$url, IO::String->new($query),
|
||||
accept => 'text/html',
|
||||
length => length($query),
|
||||
cookie => 'lemonldapidp=http://auth.idp.com/saml/metadata',
|
||||
),
|
||||
'Post SAML response to SP'
|
||||
);
|
||||
my $spId = expectCookie($res);
|
||||
expectRedirection( $res, 'http://test1.example.com/' );
|
||||
|
||||
ok( $res = $sp->_get( '/', cookie => "lemonldap=$spId" ), 'Get / on SP' );
|
||||
expectOK($res);
|
||||
expectAuthenticatedAs( $res, 'fa@badwolf.org@idp' );
|
||||
|
||||
# Verify UTF-8
|
||||
ok( $res = $sp->_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'
|
||||
);
|
||||
|
||||
ok(
|
||||
expectCookie( $res, 'lemonldapidp' ) eq
|
||||
'http://auth.idp.com/saml/metadata',
|
||||
'IDP cookie defined'
|
||||
)
|
||||
or explain(
|
||||
$res->[1],
|
||||
'Set-Cookie => lemonldapidp=http://auth.idp.com/saml/metadata; domain=.sp2.com; path=/'
|
||||
);
|
||||
( $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),
|
||||
cookie => 'lemonldapidp=http://auth.idp.com/saml/metadata',
|
||||
),
|
||||
'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' );
|
||||
|
||||
# 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'
|
||||
);
|
||||
|
||||
# The SP doesn't have an SLO endpoint for its response (Hi Renater!) , in
|
||||
# this case, the portal should display a nice user message instead of
|
||||
# erroring.
|
||||
expectOK($res);
|
||||
|
||||
ok( $res->[2]->[0] =~ /trmsg="47"/, 'Found logout message' );
|
||||
|
||||
ok(
|
||||
$res = $issuer->_get(
|
||||
'/', cookie => "lemonldap=$idpId",
|
||||
),
|
||||
'Test if user is reject on IdP'
|
||||
);
|
||||
expectReject($res);
|
||||
|
||||
switch ('sp');
|
||||
ok(
|
||||
$res = $sp->_get(
|
||||
'/',
|
||||
accept => 'text/html',
|
||||
cookie =>
|
||||
"lemonldapidp=http://auth.idp.com/saml/metadata; lemonldap=$spId"
|
||||
),
|
||||
'Test if user is reject on SP'
|
||||
);
|
||||
|
||||
expectRedirection( $res,
|
||||
qr#^http://auth.idp.com(/saml/singleSignOn)\?(SAMLRequest=.+)# );
|
||||
|
||||
switch ('sp2');
|
||||
ok(
|
||||
$res = $sp2->_get(
|
||||
'/',
|
||||
accept => 'text/html',
|
||||
cookie =>
|
||||
"lemonldapidp=http://auth.idp.com/saml/metadata; lemonldap=$sp2Id"
|
||||
),
|
||||
'User is unfortunately still logged into SP2'
|
||||
);
|
||||
expectOK($res);
|
||||
expectAuthenticatedAs( $res, 'fa@badwolf.org@idp' );
|
||||
}
|
||||
|
||||
count($maintests);
|
||||
clean_sessions();
|
||||
done_testing( count() );
|
||||
|
||||
sub switch {
|
||||
my $type = shift;
|
||||
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||
$handlerOR{$type};
|
||||
};
|
||||
}
|
||||
|
||||
sub issuer {
|
||||
return LLNG::Manager::Test->new( {
|
||||
ini => {
|
||||
logLevel => $debug,
|
||||
domain => 'idp.com',
|
||||
portal => 'http://auth.idp.com',
|
||||
authentication => 'Demo',
|
||||
userDB => 'Same',
|
||||
issuerDBSAMLActivation => 1,
|
||||
samlSPMetaDataOptions => {
|
||||
'sp.com' => {
|
||||
samlSPMetaDataOptionsEncryptionMode => 'none',
|
||||
samlSPMetaDataOptionsSignSSOMessage => 1,
|
||||
samlSPMetaDataOptionsSignSLOMessage => 1,
|
||||
samlSPMetaDataOptionsCheckSSOMessageSignature => 1,
|
||||
samlSPMetaDataOptionsCheckSLOMessageSignature => 1,
|
||||
},
|
||||
'sp2.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',
|
||||
},
|
||||
'sp2.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",
|
||||
samlOrganizationURL => "http://www.idp.com/",
|
||||
samlServicePrivateKeyEnc => "-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAnfKBDG/K0TnGT7Xu8q1N45sNWvIK91SqNg8nvN2uVeKoHADT
|
||||
csus5Xn3id5+8Q9TuMFsW9kIEeXiaPKXQa9ryfSNDhWDWloNkpGEeWif2BnHUu46
|
||||
Abu1UBWb0mH6VwcG1PR4qHruLis1odjQ1qnVDNfSEASVIppEBYjDX203ypmURIzU
|
||||
6h53GRRRlf1BLWkbVn9ysmDeR57Xw5Rsx/+tBlcnMrkv/40DSUkehQIl2JmlFrl2
|
||||
Caik+gU4pd20apA/pNLjBZF0OmGoS08AIR5NMd0KFa6CwZUUSHJqH5GFy5Y2yl4l
|
||||
g8K0klAS9q7L7aXI+eFQZhkwidjpxXnHPyxIGQIDAQABAoIBAHnfqjX3eO8SfnP5
|
||||
NURp90Td2mNHirCn0qLd9NKl1ySMPR1GgeH9SQ7Umu32EcteAUL5dOw2PiTZVmeW
|
||||
cKINgsWVftXUQcOQ4xIqWKb51QUBdy0FhxrZRSFjWxXt5iYK1PmzHfsax/g1/S9C
|
||||
RnqtFyjOy1bywkSt9jiy+9YBR2B7BDhLHlILbijWn5zaecaV4YA+L1UK4M/mehdb
|
||||
+0FVPavbGpnlqBRTY+7YXfZ/mRPCfn5DvO9lW1O0pJMmNdBh9kmm3DxHf6AkK47a
|
||||
43gO/dRWiWo2rZ/+Jw7uyqOb23U0MydP7kia0p3tzCUBPsrlgnichYG5RNFp0wqy
|
||||
3VT1TYECgYEA0Y9vENy1jJd+s7WbGrsRtSKxfZgtJr0yjSlQVYrIlwbZSGn+ndxq
|
||||
V2vVlwIgLX3pz6T40BMfk6SNx08jjy0Sgn6OAM0ILrinno8yWcSAMCmfCU0S/3O1
|
||||
55bqtcnk4XTHBHzJ5OrnrPaW5ourvJz0lcWEKMg3BXxLzaF6ZRy85nECgYEAwPMD
|
||||
LNAKLCDrUMyYFOpPyPLe7wvszcFvPipGgerSgFP1c6N7xaMUdHDYqBfuis1khPGF
|
||||
YcMHeNBYmzX6yEGbp3lrB4PHpUySmTU3mv3u9I05aahInK21gXum3uRkCWyyIF6V
|
||||
T/qeszl9mVOCp0CC4eG3IMVpaD0UKDEHVhERYCkCgYAjuTPRyA4a3Wh38ilysRkf
|
||||
q75eDqcDx5Tqg3RyYKo5NK2troP9HSnzpSpQB8i8eI53G0RfFCN5479XjqIdMi3J
|
||||
mRFUCZ+vd0L7wKVwsBK6Ix49U6o9adhElnGEc9pUpLeYiD1SjMjZr1+iBYVNLeRz
|
||||
86vH1/mpMbsqXrCis/dvwQKBgGttomHr/w3s0jftget7PirrFrbP0+wHfDGHhjRF
|
||||
kyhCFtJovrwefYALaIXGtVjw3LusYZA570oT7pGUb2naJZkMYEwR0jG1vZWx7KDO
|
||||
K6JbkxDB0pPxn7JVL2bAkPYyX8boAohCSOQO6WBZ/8+xem3bp4OGhpa0EyoBik0g
|
||||
OaVpAoGATj4SyYsE10hGT676iie8zy3fi5IPC3E+x4QlVuusaLtuY8LJA50stjtx
|
||||
gUa/JAKlZZL+gvzvOviQIxyfIChXOdTt5uiOYkdHJDbAF3NSrji7hrXq4v8UZv75
|
||||
8hBrwJZIpy6y01dRlrriHmPRtEq1pk7JX2uUg0sP5g4BEcsaCbc=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
",
|
||||
samlServicePrivateKeySig => "-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAtR/wgDqWB4Maho5V6TjcL/NbNfjgIh7GcgkrB5RZcVT1GTej
|
||||
JlMjUQdgBKBuZXQN+7/29P6UcGq1kYalURq6S8SpeJ1ofp5rBEoD/TIkvU0JOcid
|
||||
65wp+fdzXGXsfiZvHraU74jSCgjP/wqfVGRyBIQzB0SIxSpnrsigqNsE1E94toDM
|
||||
x4wovjHu/9ABAImREV7Sz83OeFF00/sghrjTEJOD/gHf04JCn9MgNOqvSTysr9LX
|
||||
Wg/oUKQDEYeTq9ux6pq/oqv1MxwONbSZPtN5yD41mi+hT8Rh+W8Je8rsiML4VMxz
|
||||
sb1l9303asw6suo5bLTISKNSbu1nt1NkpNxzywIDAQABAoIBAQCQkbvPPfP+bwC/
|
||||
IeEk1IO7qkzFWa7czR+safD0jc6OjTdNN4F716Q6yt4zEzLKu8VliiW+C23EBQiD
|
||||
7asKf4DvdTun0ExVtHDK7aEdeealSlXwz1ZtdypyILbtq1UGo/rR0v4x601rQPl0
|
||||
IrBmFf6D6FkqleNtLJmxguXpoVfLdYKNwkxH2ux+GOA9r2o5pUCQmJGDap5YWRuQ
|
||||
uB71ewJjVWujaL3e1ac/5cP7/tqWmgAiOaN8sYdD6+oWOR47bHj8JKcMBSl4y2QC
|
||||
dL31cGmmf5KqBbtISki3RXfHHjT7E3Z85CbESkKTZlEb1ar3XmepY6Z7V5UO16oz
|
||||
fFE5R6khAoGBAOl9Qb+qYVVO5ugE65ORjYVeuXykANhM9ssiY5a6zuAakWzw7Zv3
|
||||
k6PXm9p7azlEXAlTnTXVwHYMyuuzZDvQ8LRV1iBOdPuIkUAmaQ5K9ASD7VcoHexh
|
||||
k8DAKf9Ln7sTRaMdvgceRNczOmJOBIEpTZkssA/jVGXZsoyTWYl1en/ZAoGBAMaW
|
||||
RnNbSNprEV2b8UeAJ6i77c4SXwu1I8X2NLtiLScb1ETBjfrdHmdlJglfyd/0gmhH
|
||||
p/43Ku2iGUoY5KtuOI6QmahrJYQscRQhoj252VXadG6fNWWAlpgdCm9houhHb5BF
|
||||
3zge/bTr0anUe9EA7Z/ymav12rEouoNjIlhI9C5DAoGATR85a2SMt8/TB0owwdJu
|
||||
62GpZNkLCmcJkXkvaecUVAOSi2hdI4o4MwMRkK35cbX5rH74y4JqCtQY5pefgP53
|
||||
sykzDAK+MyMdzxGg2764MRGegI5Yq+5jDmSquo+xF+q6srEtRk6iMG7UVwosBLmu
|
||||
zuxqzySoiOfKSRKWnYe3SakCgYEAwWMkVkAmETXE4oDzFSsS8/mW2l//mPocTTK3
|
||||
JWe1CunJ6+8FYbAlZJEW2ngismp8+CoXybNVpbZ+pC7buKoMf6EHUgCNt0pEEFO0
|
||||
mCG9KSMk0XlPWXpArP9S4yaUq1itpzSz7QYZES+4rIcU0HLz9RgeWFyCTJWaFErc
|
||||
7laVG9sCgYBKOtk5WlIOP4BxSd2y4cYzohgwTZIs1/2kTEn1u4eH73M1xvAlHHFB
|
||||
wSF5QXgDKJ8pPAOhNWpdLO/PdtnQn91nOvTNc+ShJZzjdbneUdQVpWpoBf72uA+N
|
||||
6rIVf1JBUL2p7HFHaGdUZC7KGQ+yv6ZHrE1+7202nuDvJdvGEEdFsQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
",
|
||||
samlServicePublicKeyEnc => "-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnfKBDG/K0TnGT7Xu8q1N
|
||||
45sNWvIK91SqNg8nvN2uVeKoHADTcsus5Xn3id5+8Q9TuMFsW9kIEeXiaPKXQa9r
|
||||
yfSNDhWDWloNkpGEeWif2BnHUu46Abu1UBWb0mH6VwcG1PR4qHruLis1odjQ1qnV
|
||||
DNfSEASVIppEBYjDX203ypmURIzU6h53GRRRlf1BLWkbVn9ysmDeR57Xw5Rsx/+t
|
||||
BlcnMrkv/40DSUkehQIl2JmlFrl2Caik+gU4pd20apA/pNLjBZF0OmGoS08AIR5N
|
||||
Md0KFa6CwZUUSHJqH5GFy5Y2yl4lg8K0klAS9q7L7aXI+eFQZhkwidjpxXnHPyxI
|
||||
GQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
",
|
||||
samlServicePublicKeySig => "-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtR/wgDqWB4Maho5V6Tjc
|
||||
L/NbNfjgIh7GcgkrB5RZcVT1GTejJlMjUQdgBKBuZXQN+7/29P6UcGq1kYalURq6
|
||||
S8SpeJ1ofp5rBEoD/TIkvU0JOcid65wp+fdzXGXsfiZvHraU74jSCgjP/wqfVGRy
|
||||
BIQzB0SIxSpnrsigqNsE1E94toDMx4wovjHu/9ABAImREV7Sz83OeFF00/sghrjT
|
||||
EJOD/gHf04JCn9MgNOqvSTysr9LXWg/oUKQDEYeTq9ux6pq/oqv1MxwONbSZPtN5
|
||||
yD41mi+hT8Rh+W8Je8rsiML4VMxzsb1l9303asw6suo5bLTISKNSbu1nt1NkpNxz
|
||||
ywIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
",
|
||||
samlSPMetaDataXML => {
|
||||
"sp.com" => {
|
||||
samlSPMetaDataXML => <<EOF
|
||||
<?xml version="1.0"?>
|
||||
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
||||
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
||||
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
||||
entityID="http://auth.sp.com/saml/metadata">
|
||||
<SPSSODescriptor AuthnRequestsSigned="true"
|
||||
WantAssertionsSigned="true"
|
||||
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
||||
|
||||
<KeyDescriptor use="signing">
|
||||
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
<ds:KeyValue>
|
||||
<RSAKeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<Modulus>
|
||||
u4iToYAEmWQxgZDihGVzMMql1elPn37domWcvXeU2E4yt2hh5jkQHiFjgodfOlNeRIw5QJVlUBwr
|
||||
+CQvbaKRFXd7BrOhQIDC0TZPRVB0XHarUtsCuDekN4/2GKSzHsoToKUVPWq9thsuek3xkpsJGZNX
|
||||
7bglfEc9+QQpYTqN1rkdN1PVU0epNMokFFGho5pLRqLUV5+I/QXAL49jfTjaSxsp4UndTI8/+mGS
|
||||
RSq+nrT2zyQRM/vkj5vR9ZVz67HO/+Wk3Mx6RAwkVcMdgMAqCq8odmbI0yCRZiTL9ybKWRKqWJoK
|
||||
J0p5+Q2fPEBPupQZR09Jt/JPuLVSsGfCxi9Nqw==</Modulus>
|
||||
<Exponent>AQAB</Exponent>
|
||||
</RSAKeyValue>
|
||||
</ds:KeyValue>
|
||||
</ds:KeyInfo>
|
||||
</KeyDescriptor>
|
||||
<KeyDescriptor use="encryption">
|
||||
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
<ds:KeyValue>
|
||||
<RSAKeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<Modulus>
|
||||
sRaod2RZ8hMFBl+VhsnhyPM8l/Fj1obnBxfQIaWuHFIFfXiGe/CYHuZ5QJQLnZxHMJX6LL3Sh+Us
|
||||
og3p0jpijpcg0QgfBSEkfopKTgReYN8DiDIll0rV1XdTni7E85Nd1YyNy3ui/ZD+UShWwqu6jLVL
|
||||
R+QUm+/1LIKYb3OCBTvOlY7xHoP6NSU1+Mr+YzGBUacdO2vnNxe/PQhxIeP1zO0njuqGHkwEpy8r
|
||||
UWRZbbDn31TmKjqlhgtsz5HPhbRaYEExhyepKgBiNz+RyxtYXVhuG8OrWQDoS5gYHSjdw1CTJyix
|
||||
eJwyoqA9RGYguG5nh9zndi3LWAh7Z0lx+tIz+w==</Modulus>
|
||||
<Exponent>AQAB</Exponent>
|
||||
</RSAKeyValue>
|
||||
</ds:KeyValue>
|
||||
</ds:KeyInfo>
|
||||
</KeyDescriptor>
|
||||
<ArtifactResolutionService isDefault="true" index="0"
|
||||
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
||||
Location="http://auth.sp.com/saml/artifact" />
|
||||
<NameIDFormat>
|
||||
urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
|
||||
<NameIDFormat>
|
||||
urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName</NameIDFormat>
|
||||
<NameIDFormat>
|
||||
urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName</NameIDFormat>
|
||||
<NameIDFormat>
|
||||
urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos</NameIDFormat>
|
||||
<NameIDFormat>
|
||||
urn:oasis:names:tc:SAML:2.0:nameid-format:entity</NameIDFormat>
|
||||
<NameIDFormat>
|
||||
urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
||||
<AssertionConsumerService isDefault="true" index="0"
|
||||
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
||||
Location="http://auth.sp.com/saml/proxySingleSignOnPost" />
|
||||
<AssertionConsumerService isDefault="false" index="1"
|
||||
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
||||
Location="http://auth.sp.com/saml/proxySingleSignOnArtifact" />
|
||||
</SPSSODescriptor>
|
||||
<Organization>
|
||||
<OrganizationName xml:lang="en">org</OrganizationName>
|
||||
<OrganizationDisplayName xml:lang="en">
|
||||
org</OrganizationDisplayName>
|
||||
<OrganizationURL xml:lang="en">
|
||||
http://www.org.com</OrganizationURL>
|
||||
</Organization>
|
||||
</EntityDescriptor>
|
||||
EOF
|
||||
},
|
||||
"sp2.com" => {
|
||||
samlSPMetaDataXML => <<EOF
|
||||
<?xml version="1.0"?>
|
||||
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
||||
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
||||
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
||||
entityID="http://auth.sp2.com/saml/metadata">
|
||||
<SPSSODescriptor AuthnRequestsSigned="true"
|
||||
WantAssertionsSigned="true"
|
||||
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
||||
|
||||
<KeyDescriptor use="signing">
|
||||
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
<ds:KeyValue>
|
||||
<RSAKeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<Modulus>
|
||||
u4iToYAEmWQxgZDihGVzMMql1elPn37domWcvXeU2E4yt2hh5jkQHiFjgodfOlNeRIw5QJVlUBwr
|
||||
+CQvbaKRFXd7BrOhQIDC0TZPRVB0XHarUtsCuDekN4/2GKSzHsoToKUVPWq9thsuek3xkpsJGZNX
|
||||
7bglfEc9+QQpYTqN1rkdN1PVU0epNMokFFGho5pLRqLUV5+I/QXAL49jfTjaSxsp4UndTI8/+mGS
|
||||
RSq+nrT2zyQRM/vkj5vR9ZVz67HO/+Wk3Mx6RAwkVcMdgMAqCq8odmbI0yCRZiTL9ybKWRKqWJoK
|
||||
J0p5+Q2fPEBPupQZR09Jt/JPuLVSsGfCxi9Nqw==</Modulus>
|
||||
<Exponent>AQAB</Exponent>
|
||||
</RSAKeyValue>
|
||||
</ds:KeyValue>
|
||||
</ds:KeyInfo>
|
||||
</KeyDescriptor>
|
||||
<KeyDescriptor use="encryption">
|
||||
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
<ds:KeyValue>
|
||||
<RSAKeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<Modulus>
|
||||
sRaod2RZ8hMFBl+VhsnhyPM8l/Fj1obnBxfQIaWuHFIFfXiGe/CYHuZ5QJQLnZxHMJX6LL3Sh+Us
|
||||
og3p0jpijpcg0QgfBSEkfopKTgReYN8DiDIll0rV1XdTni7E85Nd1YyNy3ui/ZD+UShWwqu6jLVL
|
||||
R+QUm+/1LIKYb3OCBTvOlY7xHoP6NSU1+Mr+YzGBUacdO2vnNxe/PQhxIeP1zO0njuqGHkwEpy8r
|
||||
UWRZbbDn31TmKjqlhgtsz5HPhbRaYEExhyepKgBiNz+RyxtYXVhuG8OrWQDoS5gYHSjdw1CTJyix
|
||||
eJwyoqA9RGYguG5nh9zndi3LWAh7Z0lx+tIz+w==</Modulus>
|
||||
<Exponent>AQAB</Exponent>
|
||||
</RSAKeyValue>
|
||||
</ds:KeyValue>
|
||||
</ds:KeyInfo>
|
||||
</KeyDescriptor>
|
||||
<ArtifactResolutionService isDefault="true" index="0"
|
||||
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
||||
Location="http://auth.sp2.com/saml/artifact" />
|
||||
<NameIDFormat>
|
||||
urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
|
||||
<NameIDFormat>
|
||||
urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName</NameIDFormat>
|
||||
<NameIDFormat>
|
||||
urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName</NameIDFormat>
|
||||
<NameIDFormat>
|
||||
urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos</NameIDFormat>
|
||||
<NameIDFormat>
|
||||
urn:oasis:names:tc:SAML:2.0:nameid-format:entity</NameIDFormat>
|
||||
<NameIDFormat>
|
||||
urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
||||
<AssertionConsumerService isDefault="true" index="0"
|
||||
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
||||
Location="http://auth.sp2.com/saml/proxySingleSignOnPost" />
|
||||
<AssertionConsumerService isDefault="false" index="1"
|
||||
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
||||
Location="http://auth.sp2.com/saml/proxySingleSignOnArtifact" />
|
||||
</SPSSODescriptor>
|
||||
<Organization>
|
||||
<OrganizationName xml:lang="en">org</OrganizationName>
|
||||
<OrganizationDisplayName xml:lang="en">
|
||||
org</OrganizationDisplayName>
|
||||
<OrganizationURL xml:lang="en">
|
||||
http://www.org.com</OrganizationURL>
|
||||
</Organization>
|
||||
</EntityDescriptor>
|
||||
EOF
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub sp {
|
||||
return LLNG::Manager::Test->new( {
|
||||
ini => {
|
||||
logLevel => $debug,
|
||||
domain => 'sp.com',
|
||||
portal => 'http://auth.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 => 'redirect',
|
||||
samlIDPMetaDataOptionsSLOBinding => 'redirect',
|
||||
samlIDPMetaDataOptionsSignSSOMessage => 1,
|
||||
samlIDPMetaDataOptionsSignSLOMessage => 1,
|
||||
samlIDPMetaDataOptionsCheckSSOMessageSignature => 1,
|
||||
samlIDPMetaDataOptionsCheckSLOMessageSignature => 1,
|
||||
samlIDPMetaDataOptionsForceUTF8 => 1,
|
||||
}
|
||||
},
|
||||
samlIDPMetaDataExportedAttributes => {
|
||||
idp => {
|
||||
"uid" => "0;uid;;",
|
||||
"cn" => "1;cn;;",
|
||||
},
|
||||
},
|
||||
samlIDPMetaDataXML => {
|
||||
idp => {
|
||||
samlIDPMetaDataXML =>
|
||||
samlIDPMetaDataXML( 'idp', 'HTTP-Redirect' )
|
||||
}
|
||||
},
|
||||
samlOrganizationDisplayName => "SP",
|
||||
samlOrganizationName => "SP",
|
||||
samlOrganizationURL => "http://www.sp.com",
|
||||
samlServicePublicKeySig => "-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu4iToYAEmWQxgZDihGVz
|
||||
MMql1elPn37domWcvXeU2E4yt2hh5jkQHiFjgodfOlNeRIw5QJVlUBwr+CQvbaKR
|
||||
FXd7BrOhQIDC0TZPRVB0XHarUtsCuDekN4/2GKSzHsoToKUVPWq9thsuek3xkpsJ
|
||||
GZNX7bglfEc9+QQpYTqN1rkdN1PVU0epNMokFFGho5pLRqLUV5+I/QXAL49jfTja
|
||||
Sxsp4UndTI8/+mGSRSq+nrT2zyQRM/vkj5vR9ZVz67HO/+Wk3Mx6RAwkVcMdgMAq
|
||||
Cq8odmbI0yCRZiTL9ybKWRKqWJoKJ0p5+Q2fPEBPupQZR09Jt/JPuLVSsGfCxi9N
|
||||
qwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
",
|
||||
samlServicePrivateKeyEnc => "-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAsRaod2RZ8hMFBl+VhsnhyPM8l/Fj1obnBxfQIaWuHFIFfXiG
|
||||
e/CYHuZ5QJQLnZxHMJX6LL3Sh+Usog3p0jpijpcg0QgfBSEkfopKTgReYN8DiDIl
|
||||
l0rV1XdTni7E85Nd1YyNy3ui/ZD+UShWwqu6jLVLR+QUm+/1LIKYb3OCBTvOlY7x
|
||||
HoP6NSU1+Mr+YzGBUacdO2vnNxe/PQhxIeP1zO0njuqGHkwEpy8rUWRZbbDn31Tm
|
||||
Kjqlhgtsz5HPhbRaYEExhyepKgBiNz+RyxtYXVhuG8OrWQDoS5gYHSjdw1CTJyix
|
||||
eJwyoqA9RGYguG5nh9zndi3LWAh7Z0lx+tIz+wIDAQABAoIBAEkZrk8iiJKJ0WAx
|
||||
IrsyKNbXuWKLTYgnxcRCyzKofrfID+YcU39j8JeI0fKbajQUZ7qhnlTLwtU//+2h
|
||||
SqzyVu6/add/v7ZRWQw3L7cGzKK2THHzKVtLk/t7N3QroDdf1LMrQvkFP2HmcWS0
|
||||
/yN62hXtXHb/qpY4Nn+6JQyUpM5dkv8S/QjDl2NTdyWrXKzWp+4I3QLQ20f4zym+
|
||||
ir7RennziMc0HlQNcTjGAUbFULtdqEfSFWhNK7UjiRY+S0XV2xJIbGjnxUQH62fS
|
||||
w1ZzYsF7sBtoSckvfL4WfGbylhOVnliU05RLU2c67PRjj1Gskoslq1Ow/3DHR7rI
|
||||
BSBpV8ECgYEA1eHfcog7xQGDkW+cshJtFPFx+9MegB58gFW1rl0rn+tfbexvoSEA
|
||||
7G7EOTyaU6OAI+8StiRT6AYTgEU7PMM9zDykdGIWj3h0OpHGA86xhEiiaaM2DDRv
|
||||
/DEKRVlEdmRLLLY28pJVHOMYomia3mb2VKZGg2VfGtSfjg1GXD3I8OECgYEA0/X0
|
||||
U55KjZ1JQTPUgFc1WK1NxX9MaH+NcpDaolEUy3Qf3QTbfws+a9K3vwCn7EpQhrfs
|
||||
I6RVUtwFdCyfl/jzBY9Gykkg03sMgW7Qw2SCCsSt05M+jDtBbNJ7esP6PAeKFvXZ
|
||||
ZWhdeiAa4kM/P6gtvZXQ4tY4LkSbcd6b0SzzFFsCgYBjMsusFzuBd95JyfZnMNye
|
||||
5gzzu0teKMWd0CLfqB7foQ81sH9lwCTpg8ZGtbDuMdrwz6ViDR9NceQBjhqXaAZ1
|
||||
f3rW79d+22Ms9wdcJLV4oSeSzzv2FSwLT8NvvqNeNc4YArshbnVDXKDEUrfhhueh
|
||||
Ay2ZK58clpkaDVYg2hckgQKBgG3KuhtSI/YE4fwXN9yez7A2XNGPZem/IGqWo9lu
|
||||
PGJCrXqT2IqPLW82gB083r6jo+CUhonTxqqb82tA7g4PUvqvQ5Dmnk1NMKYe255K
|
||||
gp3HUO8GF2EWFIak5Hcr6oOLuDi6cjh3/euTk7ld8fYsTD0mzEOjiQhWW1p5X6bT
|
||||
LLp/AoGAHvkxA1NM1HJ3myAREbwNXxRy/nhNt4mwMkZ6hPQsW/Eg/3r7j6MJOFrm
|
||||
U8AJJjDGKe6nlXhhnMoQfJzAc0cYNgjktmJXW27fHGIwt/2QwYNFHPK3s7HTrfH6
|
||||
7T4XKT3yGeeeyC2soKJQPlGB+ETdIUnXa7eo9KVWtMTgISyx1Qk=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
",
|
||||
samlServicePrivateKeySig => "-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAu4iToYAEmWQxgZDihGVzMMql1elPn37domWcvXeU2E4yt2hh
|
||||
5jkQHiFjgodfOlNeRIw5QJVlUBwr+CQvbaKRFXd7BrOhQIDC0TZPRVB0XHarUtsC
|
||||
uDekN4/2GKSzHsoToKUVPWq9thsuek3xkpsJGZNX7bglfEc9+QQpYTqN1rkdN1PV
|
||||
U0epNMokFFGho5pLRqLUV5+I/QXAL49jfTjaSxsp4UndTI8/+mGSRSq+nrT2zyQR
|
||||
M/vkj5vR9ZVz67HO/+Wk3Mx6RAwkVcMdgMAqCq8odmbI0yCRZiTL9ybKWRKqWJoK
|
||||
J0p5+Q2fPEBPupQZR09Jt/JPuLVSsGfCxi9NqwIDAQABAoIBABE0Cjb6g3F+23vD
|
||||
SsRSeiqzrFrfOEqtXK+VGrfWzHS7V7Ozg6eW/H+HGJXUzUuQcklfg7EFA3JB41a0
|
||||
GxW3oA+UElkfCV/dcAG5NbRqGQKScEz9glZb5FikgDLqiPP+HabS/gvQSu71t2HI
|
||||
3KxSRJdwCNTp26Z28pxxYUpmELTtxd9vlHjffit2Mnt2uc8hOtFHdNavfYwvYH7o
|
||||
bmlckp7b/JVOy2Yy21O94ZWkE498jXyn71Gr+V1cnJ0RrmYbhQqIvFpFHj98Pf4O
|
||||
if3c4YmBcZ4t7PUsZUYF3ooWt8k/mdigQC3D6p80OKe+wUTYKcCN0ZdFbiURv9pg
|
||||
CsqLh+ECgYEA9vA+9QfzvXC7S5yXgTkuRiusPlNye/AiyA/0oGjmjFZ1YNsT7awH
|
||||
6BjW6WE+rS4elKJu1GaefM/cDguH4ZmJc+eKgi4LDCqYw9rr9les3aneBc8demd3
|
||||
O/Ej1Pud1QxXArBNfBYo08vEqwST9P89clJC5090U6bGK2E0rTVu1w0CgYEAwmpG
|
||||
9LbOFeGCPmwX7Avuk7tQQfRSV6q9TFZo+HxDfKYvxec846l1vBenY2rrgYhtolYJ
|
||||
YS795LYgbSWRxGfgr1GuIbP5GsjHy6/1o6bS8M++GJ7KHArb0QLAYyQweqqb164A
|
||||
NvHJkveueWnxzeOlD9j2fcjEnBHwTnqjG+17CZcCgYEAqMXawa4FsNxzpmIISpHC
|
||||
RsNindZ60Kp3mzUMhPYtXI1a/C+/lxmU7dTMTgXgyIxU6lF6XkEk4TlPtWm8HTzK
|
||||
7SS7Te4aLt6OOo5N57hUtct7q4y7IQXGQHm3e8HdRdeBQJ0u2Dhs/xSt/hTK6w/n
|
||||
91Kx11Y+s02w88UkM53pe6ECgYAF/UYwVc1liSv9BlF6WSfBb1zam09KGh1405Sq
|
||||
SxG9LlV8cFJE5TyWTdg/TNTyiaRvAt2JG+yAdkfrdOPXvCeE3yxRJ30+IP9evA4C
|
||||
O6p19sBxe7rYQFFjUAVjSIMh1E22yEqDZtGB8JV0chob8K5uHY4CdAPylu7jTA3o
|
||||
V1maAwKBgQCSGQ3yzsk4EGN2xd/JdgGDzhKyTZTQKMWYqQcsYxRAQ7Paj7u+Wkgv
|
||||
dBeKcI0HwgpLy5ZohSd2erqieIsW0pEbJWCmos4IcO8tgNfEOa5WXYdyLbj5tFwt
|
||||
ctu4/BJdijqfpMAtG8pv6k09gYjfASVytXmydGcs/0rVKYCRQA8Tow==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
",
|
||||
samlServicePublicKeyEnc => "-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsRaod2RZ8hMFBl+Vhsnh
|
||||
yPM8l/Fj1obnBxfQIaWuHFIFfXiGe/CYHuZ5QJQLnZxHMJX6LL3Sh+Usog3p0jpi
|
||||
jpcg0QgfBSEkfopKTgReYN8DiDIll0rV1XdTni7E85Nd1YyNy3ui/ZD+UShWwqu6
|
||||
jLVLR+QUm+/1LIKYb3OCBTvOlY7xHoP6NSU1+Mr+YzGBUacdO2vnNxe/PQhxIeP1
|
||||
zO0njuqGHkwEpy8rUWRZbbDn31TmKjqlhgtsz5HPhbRaYEExhyepKgBiNz+RyxtY
|
||||
XVhuG8OrWQDoS5gYHSjdw1CTJyixeJwyoqA9RGYguG5nh9zndi3LWAh7Z0lx+tIz
|
||||
+wIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
",
|
||||
samlSPSSODescriptorAuthnRequestsSigned => 1,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub sp2 {
|
||||
return LLNG::Manager::Test->new( {
|
||||
ini => {
|
||||
logLevel => $debug,
|
||||
domain => 'sp2.com',
|
||||
portal => 'http://auth.sp2.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 => 'redirect',
|
||||
samlIDPMetaDataOptionsSLOBinding => 'redirect',
|
||||
samlIDPMetaDataOptionsSignSSOMessage => 1,
|
||||
samlIDPMetaDataOptionsSignSLOMessage => 1,
|
||||
samlIDPMetaDataOptionsCheckSSOMessageSignature => 1,
|
||||
samlIDPMetaDataOptionsCheckSLOMessageSignature => 1,
|
||||
samlIDPMetaDataOptionsForceUTF8 => 1,
|
||||
}
|
||||
},
|
||||
samlIDPMetaDataExportedAttributes => {
|
||||
idp => {
|
||||
"uid" => "0;uid;;",
|
||||
"cn" => "1;cn;;",
|
||||
},
|
||||
},
|
||||
samlIDPMetaDataXML => {
|
||||
idp => {
|
||||
samlIDPMetaDataXML =>
|
||||
samlIDPMetaDataXML( 'idp', 'HTTP-Redirect' )
|
||||
}
|
||||
},
|
||||
samlOrganizationDisplayName => "SP",
|
||||
samlOrganizationName => "SP",
|
||||
samlOrganizationURL => "http://www.sp2.com",
|
||||
samlServicePublicKeySig => "-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu4iToYAEmWQxgZDihGVz
|
||||
MMql1elPn37domWcvXeU2E4yt2hh5jkQHiFjgodfOlNeRIw5QJVlUBwr+CQvbaKR
|
||||
FXd7BrOhQIDC0TZPRVB0XHarUtsCuDekN4/2GKSzHsoToKUVPWq9thsuek3xkpsJ
|
||||
GZNX7bglfEc9+QQpYTqN1rkdN1PVU0epNMokFFGho5pLRqLUV5+I/QXAL49jfTja
|
||||
Sxsp4UndTI8/+mGSRSq+nrT2zyQRM/vkj5vR9ZVz67HO/+Wk3Mx6RAwkVcMdgMAq
|
||||
Cq8odmbI0yCRZiTL9ybKWRKqWJoKJ0p5+Q2fPEBPupQZR09Jt/JPuLVSsGfCxi9N
|
||||
qwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
",
|
||||
samlServicePrivateKeyEnc => "-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAsRaod2RZ8hMFBl+VhsnhyPM8l/Fj1obnBxfQIaWuHFIFfXiG
|
||||
e/CYHuZ5QJQLnZxHMJX6LL3Sh+Usog3p0jpijpcg0QgfBSEkfopKTgReYN8DiDIl
|
||||
l0rV1XdTni7E85Nd1YyNy3ui/ZD+UShWwqu6jLVLR+QUm+/1LIKYb3OCBTvOlY7x
|
||||
HoP6NSU1+Mr+YzGBUacdO2vnNxe/PQhxIeP1zO0njuqGHkwEpy8rUWRZbbDn31Tm
|
||||
Kjqlhgtsz5HPhbRaYEExhyepKgBiNz+RyxtYXVhuG8OrWQDoS5gYHSjdw1CTJyix
|
||||
eJwyoqA9RGYguG5nh9zndi3LWAh7Z0lx+tIz+wIDAQABAoIBAEkZrk8iiJKJ0WAx
|
||||
IrsyKNbXuWKLTYgnxcRCyzKofrfID+YcU39j8JeI0fKbajQUZ7qhnlTLwtU//+2h
|
||||
SqzyVu6/add/v7ZRWQw3L7cGzKK2THHzKVtLk/t7N3QroDdf1LMrQvkFP2HmcWS0
|
||||
/yN62hXtXHb/qpY4Nn+6JQyUpM5dkv8S/QjDl2NTdyWrXKzWp+4I3QLQ20f4zym+
|
||||
ir7RennziMc0HlQNcTjGAUbFULtdqEfSFWhNK7UjiRY+S0XV2xJIbGjnxUQH62fS
|
||||
w1ZzYsF7sBtoSckvfL4WfGbylhOVnliU05RLU2c67PRjj1Gskoslq1Ow/3DHR7rI
|
||||
BSBpV8ECgYEA1eHfcog7xQGDkW+cshJtFPFx+9MegB58gFW1rl0rn+tfbexvoSEA
|
||||
7G7EOTyaU6OAI+8StiRT6AYTgEU7PMM9zDykdGIWj3h0OpHGA86xhEiiaaM2DDRv
|
||||
/DEKRVlEdmRLLLY28pJVHOMYomia3mb2VKZGg2VfGtSfjg1GXD3I8OECgYEA0/X0
|
||||
U55KjZ1JQTPUgFc1WK1NxX9MaH+NcpDaolEUy3Qf3QTbfws+a9K3vwCn7EpQhrfs
|
||||
I6RVUtwFdCyfl/jzBY9Gykkg03sMgW7Qw2SCCsSt05M+jDtBbNJ7esP6PAeKFvXZ
|
||||
ZWhdeiAa4kM/P6gtvZXQ4tY4LkSbcd6b0SzzFFsCgYBjMsusFzuBd95JyfZnMNye
|
||||
5gzzu0teKMWd0CLfqB7foQ81sH9lwCTpg8ZGtbDuMdrwz6ViDR9NceQBjhqXaAZ1
|
||||
f3rW79d+22Ms9wdcJLV4oSeSzzv2FSwLT8NvvqNeNc4YArshbnVDXKDEUrfhhueh
|
||||
Ay2ZK58clpkaDVYg2hckgQKBgG3KuhtSI/YE4fwXN9yez7A2XNGPZem/IGqWo9lu
|
||||
PGJCrXqT2IqPLW82gB083r6jo+CUhonTxqqb82tA7g4PUvqvQ5Dmnk1NMKYe255K
|
||||
gp3HUO8GF2EWFIak5Hcr6oOLuDi6cjh3/euTk7ld8fYsTD0mzEOjiQhWW1p5X6bT
|
||||
LLp/AoGAHvkxA1NM1HJ3myAREbwNXxRy/nhNt4mwMkZ6hPQsW/Eg/3r7j6MJOFrm
|
||||
U8AJJjDGKe6nlXhhnMoQfJzAc0cYNgjktmJXW27fHGIwt/2QwYNFHPK3s7HTrfH6
|
||||
7T4XKT3yGeeeyC2soKJQPlGB+ETdIUnXa7eo9KVWtMTgISyx1Qk=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
",
|
||||
samlServicePrivateKeySig => "-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAu4iToYAEmWQxgZDihGVzMMql1elPn37domWcvXeU2E4yt2hh
|
||||
5jkQHiFjgodfOlNeRIw5QJVlUBwr+CQvbaKRFXd7BrOhQIDC0TZPRVB0XHarUtsC
|
||||
uDekN4/2GKSzHsoToKUVPWq9thsuek3xkpsJGZNX7bglfEc9+QQpYTqN1rkdN1PV
|
||||
U0epNMokFFGho5pLRqLUV5+I/QXAL49jfTjaSxsp4UndTI8/+mGSRSq+nrT2zyQR
|
||||
M/vkj5vR9ZVz67HO/+Wk3Mx6RAwkVcMdgMAqCq8odmbI0yCRZiTL9ybKWRKqWJoK
|
||||
J0p5+Q2fPEBPupQZR09Jt/JPuLVSsGfCxi9NqwIDAQABAoIBABE0Cjb6g3F+23vD
|
||||
SsRSeiqzrFrfOEqtXK+VGrfWzHS7V7Ozg6eW/H+HGJXUzUuQcklfg7EFA3JB41a0
|
||||
GxW3oA+UElkfCV/dcAG5NbRqGQKScEz9glZb5FikgDLqiPP+HabS/gvQSu71t2HI
|
||||
3KxSRJdwCNTp26Z28pxxYUpmELTtxd9vlHjffit2Mnt2uc8hOtFHdNavfYwvYH7o
|
||||
bmlckp7b/JVOy2Yy21O94ZWkE498jXyn71Gr+V1cnJ0RrmYbhQqIvFpFHj98Pf4O
|
||||
if3c4YmBcZ4t7PUsZUYF3ooWt8k/mdigQC3D6p80OKe+wUTYKcCN0ZdFbiURv9pg
|
||||
CsqLh+ECgYEA9vA+9QfzvXC7S5yXgTkuRiusPlNye/AiyA/0oGjmjFZ1YNsT7awH
|
||||
6BjW6WE+rS4elKJu1GaefM/cDguH4ZmJc+eKgi4LDCqYw9rr9les3aneBc8demd3
|
||||
O/Ej1Pud1QxXArBNfBYo08vEqwST9P89clJC5090U6bGK2E0rTVu1w0CgYEAwmpG
|
||||
9LbOFeGCPmwX7Avuk7tQQfRSV6q9TFZo+HxDfKYvxec846l1vBenY2rrgYhtolYJ
|
||||
YS795LYgbSWRxGfgr1GuIbP5GsjHy6/1o6bS8M++GJ7KHArb0QLAYyQweqqb164A
|
||||
NvHJkveueWnxzeOlD9j2fcjEnBHwTnqjG+17CZcCgYEAqMXawa4FsNxzpmIISpHC
|
||||
RsNindZ60Kp3mzUMhPYtXI1a/C+/lxmU7dTMTgXgyIxU6lF6XkEk4TlPtWm8HTzK
|
||||
7SS7Te4aLt6OOo5N57hUtct7q4y7IQXGQHm3e8HdRdeBQJ0u2Dhs/xSt/hTK6w/n
|
||||
91Kx11Y+s02w88UkM53pe6ECgYAF/UYwVc1liSv9BlF6WSfBb1zam09KGh1405Sq
|
||||
SxG9LlV8cFJE5TyWTdg/TNTyiaRvAt2JG+yAdkfrdOPXvCeE3yxRJ30+IP9evA4C
|
||||
O6p19sBxe7rYQFFjUAVjSIMh1E22yEqDZtGB8JV0chob8K5uHY4CdAPylu7jTA3o
|
||||
V1maAwKBgQCSGQ3yzsk4EGN2xd/JdgGDzhKyTZTQKMWYqQcsYxRAQ7Paj7u+Wkgv
|
||||
dBeKcI0HwgpLy5ZohSd2erqieIsW0pEbJWCmos4IcO8tgNfEOa5WXYdyLbj5tFwt
|
||||
ctu4/BJdijqfpMAtG8pv6k09gYjfASVytXmydGcs/0rVKYCRQA8Tow==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
",
|
||||
samlServicePublicKeyEnc => "-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsRaod2RZ8hMFBl+Vhsnh
|
||||
yPM8l/Fj1obnBxfQIaWuHFIFfXiGe/CYHuZ5QJQLnZxHMJX6LL3Sh+Usog3p0jpi
|
||||
jpcg0QgfBSEkfopKTgReYN8DiDIll0rV1XdTni7E85Nd1YyNy3ui/ZD+UShWwqu6
|
||||
jLVLR+QUm+/1LIKYb3OCBTvOlY7xHoP6NSU1+Mr+YzGBUacdO2vnNxe/PQhxIeP1
|
||||
zO0njuqGHkwEpy8rUWRZbbDn31TmKjqlhgtsz5HPhbRaYEExhyepKgBiNz+RyxtY
|
||||
XVhuG8OrWQDoS5gYHSjdw1CTJyixeJwyoqA9RGYguG5nh9zndi3LWAh7Z0lx+tIz
|
||||
+wIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
",
|
||||
samlSPSSODescriptorAuthnRequestsSigned => 1,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
|
@ -0,0 +1,712 @@
|
|||
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 = 27;
|
||||
my $debug = 'error';
|
||||
my ( $issuer, $sp, $sp2, $res );
|
||||
my %handlerOR = ( issuer => [], sp => [], sp2 => [] );
|
||||
|
||||
# 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
|
||||
ok( $issuer = issuer(), 'Issuer portal' );
|
||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||
switch ('sp');
|
||||
&Lemonldap::NG::Handler::Main::cfgNum( 0, 0 );
|
||||
|
||||
ok( $sp = sp(), 'SP portal' );
|
||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||
|
||||
ok( $sp2 = sp2(), 'SP2 portal' );
|
||||
$handlerOR{sp2} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||
|
||||
# Simple SP access
|
||||
my $res;
|
||||
ok(
|
||||
$res = $sp->_get(
|
||||
'/',
|
||||
accept => 'text/html',
|
||||
query => 'url=aHR0cDovL3Rlc3QxLmV4YW1wbGUuY29tLw=='
|
||||
),
|
||||
'Unauth SP request'
|
||||
);
|
||||
my ( $host, $url, $query );
|
||||
ok(
|
||||
expectCookie( $res, 'lemonldapidp' ) eq
|
||||
'http://auth.idp.com/saml/metadata',
|
||||
'IDP cookie defined'
|
||||
)
|
||||
or explain(
|
||||
$res->[1],
|
||||
'Set-Cookie => lemonldapidp=http://auth.idp.com/saml/metadata; domain=.sp.com; path=/'
|
||||
);
|
||||
( $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/^.*?<form.*?>//s;
|
||||
$body =~ s#</form>.*$##s;
|
||||
my %fields =
|
||||
( $body =~ /<input type="hidden".+?name="(.+?)".+?value="(.*?)"/sg );
|
||||
$fields{user} = $fields{password} = 'french';
|
||||
use URI::Escape;
|
||||
$query =
|
||||
join( '&', map { "$_=" . uri_escape( $fields{$_} ) } keys %fields );
|
||||
ok(
|
||||
$res = $issuer->_post(
|
||||
$url,
|
||||
IO::String->new($query),
|
||||
accept => 'text/html',
|
||||
cookie => $pdata,
|
||||
length => length($query),
|
||||
),
|
||||
'Post authentication'
|
||||
);
|
||||
expectOK($res);
|
||||
my $idpId = expectCookie($res);
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $res, 'auth.sp.com', '/saml/proxySingleSignOnPost',
|
||||
'SAMLResponse', 'RelayState' );
|
||||
|
||||
# Post SAML response to SP
|
||||
switch ('sp');
|
||||
ok(
|
||||
$res = $sp->_post(
|
||||
$url, IO::String->new($query),
|
||||
accept => 'text/html',
|
||||
length => length($query),
|
||||
cookie => 'lemonldapidp=http://auth.idp.com/saml/metadata',
|
||||
),
|
||||
'Post SAML response to SP'
|
||||
);
|
||||
my $spId = expectCookie($res);
|
||||
expectRedirection( $res, 'http://test1.example.com/' );
|
||||
|
||||
ok( $res = $sp->_get( '/', cookie => "lemonldap=$spId" ), 'Get / on SP' );
|
||||
expectOK($res);
|
||||
expectAuthenticatedAs( $res, 'fa@badwolf.org@idp' );
|
||||
|
||||
# Verify UTF-8
|
||||
ok( $res = $sp->_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'
|
||||
);
|
||||
|
||||
ok(
|
||||
expectCookie( $res, 'lemonldapidp' ) eq
|
||||
'http://auth.idp.com/saml/metadata',
|
||||
'IDP cookie defined'
|
||||
)
|
||||
or explain(
|
||||
$res->[1],
|
||||
'Set-Cookie => lemonldapidp=http://auth.idp.com/saml/metadata; domain=.sp2.com; path=/'
|
||||
);
|
||||
( $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),
|
||||
cookie => 'lemonldapidp=http://auth.idp.com/saml/metadata',
|
||||
),
|
||||
'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' );
|
||||
|
||||
# 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 $relaypage = $res;
|
||||
|
||||
ok( $res->[2]->[0] =~
|
||||
m%<iframe src="http://auth.sp2.com/saml/proxySingleLogout\?([^"]*)"%
|
||||
);
|
||||
my $iframe = $1;
|
||||
|
||||
# Load iframe
|
||||
switch ('sp2');
|
||||
ok(
|
||||
$res = $sp2->_get(
|
||||
'/saml/proxySingleLogout',
|
||||
query => $iframe,
|
||||
cookie => "lemonldap=$sp2Id",
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Start logout from SP2'
|
||||
);
|
||||
|
||||
( $url, $query ) = expectRedirection( $res,
|
||||
qr#^http://auth.idp.com(/saml/singleLogoutReturn)\?(SAMLResponse=.+)# );
|
||||
|
||||
# Get OK icon from IDP
|
||||
switch ('issuer');
|
||||
ok(
|
||||
$res = $issuer->_get(
|
||||
$url,
|
||||
query => $query,
|
||||
accept => 'text/html',
|
||||
),
|
||||
'get SAML response from IDP',
|
||||
);
|
||||
expectRedirection( $res, "http://auth.idp.com/static/common/icons/ok.png" );
|
||||
|
||||
# Post global logout form
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $relaypage, 'auth.idp.com',
|
||||
'/saml/relaySingleLogoutTermination', 'relay' );
|
||||
|
||||
ok(
|
||||
$res = $issuer->_post(
|
||||
$url,
|
||||
IO::String->new($query),
|
||||
accept => 'text/html',
|
||||
length => length($query),
|
||||
),
|
||||
'Post final logout'
|
||||
);
|
||||
( $url, $query ) = expectRedirection( $res,
|
||||
qr#^http://auth.sp.com(/saml/proxySingleLogoutReturn)\?(SAMLResponse=.+)#
|
||||
);
|
||||
|
||||
# Send SAML response to SP
|
||||
switch ('sp');
|
||||
ok(
|
||||
$res = $sp->_get(
|
||||
$url,
|
||||
query => $query,
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Send SAML logout response to SP'
|
||||
);
|
||||
|
||||
# Test if logout is done
|
||||
switch ('issuer');
|
||||
ok(
|
||||
$res = $issuer->_get(
|
||||
'/', cookie => "lemonldap=$idpId",
|
||||
),
|
||||
'Test if user is reject on IdP'
|
||||
);
|
||||
expectReject($res);
|
||||
|
||||
switch ('sp');
|
||||
ok(
|
||||
$res = $sp->_get(
|
||||
'/',
|
||||
accept => 'text/html',
|
||||
cookie =>
|
||||
"lemonldapidp=http://auth.idp.com/saml/metadata; lemonldap=$spId"
|
||||
),
|
||||
'Test if user is reject on SP'
|
||||
);
|
||||
expectRedirection( $res,
|
||||
qr#^http://auth.idp.com(/saml/singleSignOn)\?(SAMLRequest=.+)# );
|
||||
|
||||
switch ('sp2');
|
||||
ok(
|
||||
$res = $sp2->_get(
|
||||
'/',
|
||||
accept => 'text/html',
|
||||
cookie =>
|
||||
"lemonldapidp=http://auth.idp.com/saml/metadata; lemonldap=$sp2Id"
|
||||
),
|
||||
'Test if user is reject on SP2'
|
||||
);
|
||||
expectRedirection( $res,
|
||||
qr#^http://auth.idp.com(/saml/singleSignOn)\?(SAMLRequest=.+)# );
|
||||
}
|
||||
|
||||
count($maintests);
|
||||
clean_sessions();
|
||||
done_testing( count() );
|
||||
|
||||
sub switch {
|
||||
my $type = shift;
|
||||
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||
$handlerOR{$type};
|
||||
};
|
||||
}
|
||||
|
||||
sub issuer {
|
||||
return LLNG::Manager::Test->new( {
|
||||
ini => {
|
||||
logLevel => $debug,
|
||||
domain => 'idp.com',
|
||||
portal => 'http://auth.idp.com',
|
||||
authentication => 'Demo',
|
||||
userDB => 'Same',
|
||||
issuerDBSAMLActivation => 1,
|
||||
samlSPMetaDataOptions => {
|
||||
'sp.com' => {
|
||||
samlSPMetaDataOptionsEncryptionMode => 'none',
|
||||
samlSPMetaDataOptionsSignSSOMessage => 1,
|
||||
samlSPMetaDataOptionsSignSLOMessage => 1,
|
||||
samlSPMetaDataOptionsCheckSSOMessageSignature => 1,
|
||||
samlSPMetaDataOptionsCheckSLOMessageSignature => 1,
|
||||
},
|
||||
'sp2.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',
|
||||
},
|
||||
'sp2.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",
|
||||
samlOrganizationURL => "http://www.idp.com/",
|
||||
samlServicePrivateKeyEnc => "-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAnfKBDG/K0TnGT7Xu8q1N45sNWvIK91SqNg8nvN2uVeKoHADT
|
||||
csus5Xn3id5+8Q9TuMFsW9kIEeXiaPKXQa9ryfSNDhWDWloNkpGEeWif2BnHUu46
|
||||
Abu1UBWb0mH6VwcG1PR4qHruLis1odjQ1qnVDNfSEASVIppEBYjDX203ypmURIzU
|
||||
6h53GRRRlf1BLWkbVn9ysmDeR57Xw5Rsx/+tBlcnMrkv/40DSUkehQIl2JmlFrl2
|
||||
Caik+gU4pd20apA/pNLjBZF0OmGoS08AIR5NMd0KFa6CwZUUSHJqH5GFy5Y2yl4l
|
||||
g8K0klAS9q7L7aXI+eFQZhkwidjpxXnHPyxIGQIDAQABAoIBAHnfqjX3eO8SfnP5
|
||||
NURp90Td2mNHirCn0qLd9NKl1ySMPR1GgeH9SQ7Umu32EcteAUL5dOw2PiTZVmeW
|
||||
cKINgsWVftXUQcOQ4xIqWKb51QUBdy0FhxrZRSFjWxXt5iYK1PmzHfsax/g1/S9C
|
||||
RnqtFyjOy1bywkSt9jiy+9YBR2B7BDhLHlILbijWn5zaecaV4YA+L1UK4M/mehdb
|
||||
+0FVPavbGpnlqBRTY+7YXfZ/mRPCfn5DvO9lW1O0pJMmNdBh9kmm3DxHf6AkK47a
|
||||
43gO/dRWiWo2rZ/+Jw7uyqOb23U0MydP7kia0p3tzCUBPsrlgnichYG5RNFp0wqy
|
||||
3VT1TYECgYEA0Y9vENy1jJd+s7WbGrsRtSKxfZgtJr0yjSlQVYrIlwbZSGn+ndxq
|
||||
V2vVlwIgLX3pz6T40BMfk6SNx08jjy0Sgn6OAM0ILrinno8yWcSAMCmfCU0S/3O1
|
||||
55bqtcnk4XTHBHzJ5OrnrPaW5ourvJz0lcWEKMg3BXxLzaF6ZRy85nECgYEAwPMD
|
||||
LNAKLCDrUMyYFOpPyPLe7wvszcFvPipGgerSgFP1c6N7xaMUdHDYqBfuis1khPGF
|
||||
YcMHeNBYmzX6yEGbp3lrB4PHpUySmTU3mv3u9I05aahInK21gXum3uRkCWyyIF6V
|
||||
T/qeszl9mVOCp0CC4eG3IMVpaD0UKDEHVhERYCkCgYAjuTPRyA4a3Wh38ilysRkf
|
||||
q75eDqcDx5Tqg3RyYKo5NK2troP9HSnzpSpQB8i8eI53G0RfFCN5479XjqIdMi3J
|
||||
mRFUCZ+vd0L7wKVwsBK6Ix49U6o9adhElnGEc9pUpLeYiD1SjMjZr1+iBYVNLeRz
|
||||
86vH1/mpMbsqXrCis/dvwQKBgGttomHr/w3s0jftget7PirrFrbP0+wHfDGHhjRF
|
||||
kyhCFtJovrwefYALaIXGtVjw3LusYZA570oT7pGUb2naJZkMYEwR0jG1vZWx7KDO
|
||||
K6JbkxDB0pPxn7JVL2bAkPYyX8boAohCSOQO6WBZ/8+xem3bp4OGhpa0EyoBik0g
|
||||
OaVpAoGATj4SyYsE10hGT676iie8zy3fi5IPC3E+x4QlVuusaLtuY8LJA50stjtx
|
||||
gUa/JAKlZZL+gvzvOviQIxyfIChXOdTt5uiOYkdHJDbAF3NSrji7hrXq4v8UZv75
|
||||
8hBrwJZIpy6y01dRlrriHmPRtEq1pk7JX2uUg0sP5g4BEcsaCbc=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
",
|
||||
samlServicePrivateKeySig => "-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAtR/wgDqWB4Maho5V6TjcL/NbNfjgIh7GcgkrB5RZcVT1GTej
|
||||
JlMjUQdgBKBuZXQN+7/29P6UcGq1kYalURq6S8SpeJ1ofp5rBEoD/TIkvU0JOcid
|
||||
65wp+fdzXGXsfiZvHraU74jSCgjP/wqfVGRyBIQzB0SIxSpnrsigqNsE1E94toDM
|
||||
x4wovjHu/9ABAImREV7Sz83OeFF00/sghrjTEJOD/gHf04JCn9MgNOqvSTysr9LX
|
||||
Wg/oUKQDEYeTq9ux6pq/oqv1MxwONbSZPtN5yD41mi+hT8Rh+W8Je8rsiML4VMxz
|
||||
sb1l9303asw6suo5bLTISKNSbu1nt1NkpNxzywIDAQABAoIBAQCQkbvPPfP+bwC/
|
||||
IeEk1IO7qkzFWa7czR+safD0jc6OjTdNN4F716Q6yt4zEzLKu8VliiW+C23EBQiD
|
||||
7asKf4DvdTun0ExVtHDK7aEdeealSlXwz1ZtdypyILbtq1UGo/rR0v4x601rQPl0
|
||||
IrBmFf6D6FkqleNtLJmxguXpoVfLdYKNwkxH2ux+GOA9r2o5pUCQmJGDap5YWRuQ
|
||||
uB71ewJjVWujaL3e1ac/5cP7/tqWmgAiOaN8sYdD6+oWOR47bHj8JKcMBSl4y2QC
|
||||
dL31cGmmf5KqBbtISki3RXfHHjT7E3Z85CbESkKTZlEb1ar3XmepY6Z7V5UO16oz
|
||||
fFE5R6khAoGBAOl9Qb+qYVVO5ugE65ORjYVeuXykANhM9ssiY5a6zuAakWzw7Zv3
|
||||
k6PXm9p7azlEXAlTnTXVwHYMyuuzZDvQ8LRV1iBOdPuIkUAmaQ5K9ASD7VcoHexh
|
||||
k8DAKf9Ln7sTRaMdvgceRNczOmJOBIEpTZkssA/jVGXZsoyTWYl1en/ZAoGBAMaW
|
||||
RnNbSNprEV2b8UeAJ6i77c4SXwu1I8X2NLtiLScb1ETBjfrdHmdlJglfyd/0gmhH
|
||||
p/43Ku2iGUoY5KtuOI6QmahrJYQscRQhoj252VXadG6fNWWAlpgdCm9houhHb5BF
|
||||
3zge/bTr0anUe9EA7Z/ymav12rEouoNjIlhI9C5DAoGATR85a2SMt8/TB0owwdJu
|
||||
62GpZNkLCmcJkXkvaecUVAOSi2hdI4o4MwMRkK35cbX5rH74y4JqCtQY5pefgP53
|
||||
sykzDAK+MyMdzxGg2764MRGegI5Yq+5jDmSquo+xF+q6srEtRk6iMG7UVwosBLmu
|
||||
zuxqzySoiOfKSRKWnYe3SakCgYEAwWMkVkAmETXE4oDzFSsS8/mW2l//mPocTTK3
|
||||
JWe1CunJ6+8FYbAlZJEW2ngismp8+CoXybNVpbZ+pC7buKoMf6EHUgCNt0pEEFO0
|
||||
mCG9KSMk0XlPWXpArP9S4yaUq1itpzSz7QYZES+4rIcU0HLz9RgeWFyCTJWaFErc
|
||||
7laVG9sCgYBKOtk5WlIOP4BxSd2y4cYzohgwTZIs1/2kTEn1u4eH73M1xvAlHHFB
|
||||
wSF5QXgDKJ8pPAOhNWpdLO/PdtnQn91nOvTNc+ShJZzjdbneUdQVpWpoBf72uA+N
|
||||
6rIVf1JBUL2p7HFHaGdUZC7KGQ+yv6ZHrE1+7202nuDvJdvGEEdFsQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
",
|
||||
samlServicePublicKeyEnc => "-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnfKBDG/K0TnGT7Xu8q1N
|
||||
45sNWvIK91SqNg8nvN2uVeKoHADTcsus5Xn3id5+8Q9TuMFsW9kIEeXiaPKXQa9r
|
||||
yfSNDhWDWloNkpGEeWif2BnHUu46Abu1UBWb0mH6VwcG1PR4qHruLis1odjQ1qnV
|
||||
DNfSEASVIppEBYjDX203ypmURIzU6h53GRRRlf1BLWkbVn9ysmDeR57Xw5Rsx/+t
|
||||
BlcnMrkv/40DSUkehQIl2JmlFrl2Caik+gU4pd20apA/pNLjBZF0OmGoS08AIR5N
|
||||
Md0KFa6CwZUUSHJqH5GFy5Y2yl4lg8K0klAS9q7L7aXI+eFQZhkwidjpxXnHPyxI
|
||||
GQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
",
|
||||
samlServicePublicKeySig => "-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtR/wgDqWB4Maho5V6Tjc
|
||||
L/NbNfjgIh7GcgkrB5RZcVT1GTejJlMjUQdgBKBuZXQN+7/29P6UcGq1kYalURq6
|
||||
S8SpeJ1ofp5rBEoD/TIkvU0JOcid65wp+fdzXGXsfiZvHraU74jSCgjP/wqfVGRy
|
||||
BIQzB0SIxSpnrsigqNsE1E94toDMx4wovjHu/9ABAImREV7Sz83OeFF00/sghrjT
|
||||
EJOD/gHf04JCn9MgNOqvSTysr9LXWg/oUKQDEYeTq9ux6pq/oqv1MxwONbSZPtN5
|
||||
yD41mi+hT8Rh+W8Je8rsiML4VMxzsb1l9303asw6suo5bLTISKNSbu1nt1NkpNxz
|
||||
ywIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
",
|
||||
samlSPMetaDataXML => {
|
||||
"sp.com" => {
|
||||
samlSPMetaDataXML =>
|
||||
samlSPMetaDataXML( 'sp', 'HTTP-Redirect' )
|
||||
},
|
||||
"sp2.com" => {
|
||||
samlSPMetaDataXML =>
|
||||
samlSPMetaDataXML( 'sp2', 'HTTP-Redirect' )
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub sp {
|
||||
return LLNG::Manager::Test->new( {
|
||||
ini => {
|
||||
logLevel => $debug,
|
||||
domain => 'sp.com',
|
||||
portal => 'http://auth.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 => 'redirect',
|
||||
samlIDPMetaDataOptionsSLOBinding => 'redirect',
|
||||
samlIDPMetaDataOptionsSignSSOMessage => 1,
|
||||
samlIDPMetaDataOptionsSignSLOMessage => 1,
|
||||
samlIDPMetaDataOptionsCheckSSOMessageSignature => 1,
|
||||
samlIDPMetaDataOptionsCheckSLOMessageSignature => 1,
|
||||
samlIDPMetaDataOptionsForceUTF8 => 1,
|
||||
}
|
||||
},
|
||||
samlIDPMetaDataExportedAttributes => {
|
||||
idp => {
|
||||
"uid" => "0;uid;;",
|
||||
"cn" => "1;cn;;",
|
||||
},
|
||||
},
|
||||
samlIDPMetaDataXML => {
|
||||
idp => {
|
||||
samlIDPMetaDataXML =>
|
||||
samlIDPMetaDataXML( 'idp', 'HTTP-Redirect' )
|
||||
}
|
||||
},
|
||||
samlOrganizationDisplayName => "SP",
|
||||
samlOrganizationName => "SP",
|
||||
samlOrganizationURL => "http://www.sp.com",
|
||||
samlServicePublicKeySig => "-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu4iToYAEmWQxgZDihGVz
|
||||
MMql1elPn37domWcvXeU2E4yt2hh5jkQHiFjgodfOlNeRIw5QJVlUBwr+CQvbaKR
|
||||
FXd7BrOhQIDC0TZPRVB0XHarUtsCuDekN4/2GKSzHsoToKUVPWq9thsuek3xkpsJ
|
||||
GZNX7bglfEc9+QQpYTqN1rkdN1PVU0epNMokFFGho5pLRqLUV5+I/QXAL49jfTja
|
||||
Sxsp4UndTI8/+mGSRSq+nrT2zyQRM/vkj5vR9ZVz67HO/+Wk3Mx6RAwkVcMdgMAq
|
||||
Cq8odmbI0yCRZiTL9ybKWRKqWJoKJ0p5+Q2fPEBPupQZR09Jt/JPuLVSsGfCxi9N
|
||||
qwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
",
|
||||
samlServicePrivateKeyEnc => "-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAsRaod2RZ8hMFBl+VhsnhyPM8l/Fj1obnBxfQIaWuHFIFfXiG
|
||||
e/CYHuZ5QJQLnZxHMJX6LL3Sh+Usog3p0jpijpcg0QgfBSEkfopKTgReYN8DiDIl
|
||||
l0rV1XdTni7E85Nd1YyNy3ui/ZD+UShWwqu6jLVLR+QUm+/1LIKYb3OCBTvOlY7x
|
||||
HoP6NSU1+Mr+YzGBUacdO2vnNxe/PQhxIeP1zO0njuqGHkwEpy8rUWRZbbDn31Tm
|
||||
Kjqlhgtsz5HPhbRaYEExhyepKgBiNz+RyxtYXVhuG8OrWQDoS5gYHSjdw1CTJyix
|
||||
eJwyoqA9RGYguG5nh9zndi3LWAh7Z0lx+tIz+wIDAQABAoIBAEkZrk8iiJKJ0WAx
|
||||
IrsyKNbXuWKLTYgnxcRCyzKofrfID+YcU39j8JeI0fKbajQUZ7qhnlTLwtU//+2h
|
||||
SqzyVu6/add/v7ZRWQw3L7cGzKK2THHzKVtLk/t7N3QroDdf1LMrQvkFP2HmcWS0
|
||||
/yN62hXtXHb/qpY4Nn+6JQyUpM5dkv8S/QjDl2NTdyWrXKzWp+4I3QLQ20f4zym+
|
||||
ir7RennziMc0HlQNcTjGAUbFULtdqEfSFWhNK7UjiRY+S0XV2xJIbGjnxUQH62fS
|
||||
w1ZzYsF7sBtoSckvfL4WfGbylhOVnliU05RLU2c67PRjj1Gskoslq1Ow/3DHR7rI
|
||||
BSBpV8ECgYEA1eHfcog7xQGDkW+cshJtFPFx+9MegB58gFW1rl0rn+tfbexvoSEA
|
||||
7G7EOTyaU6OAI+8StiRT6AYTgEU7PMM9zDykdGIWj3h0OpHGA86xhEiiaaM2DDRv
|
||||
/DEKRVlEdmRLLLY28pJVHOMYomia3mb2VKZGg2VfGtSfjg1GXD3I8OECgYEA0/X0
|
||||
U55KjZ1JQTPUgFc1WK1NxX9MaH+NcpDaolEUy3Qf3QTbfws+a9K3vwCn7EpQhrfs
|
||||
I6RVUtwFdCyfl/jzBY9Gykkg03sMgW7Qw2SCCsSt05M+jDtBbNJ7esP6PAeKFvXZ
|
||||
ZWhdeiAa4kM/P6gtvZXQ4tY4LkSbcd6b0SzzFFsCgYBjMsusFzuBd95JyfZnMNye
|
||||
5gzzu0teKMWd0CLfqB7foQ81sH9lwCTpg8ZGtbDuMdrwz6ViDR9NceQBjhqXaAZ1
|
||||
f3rW79d+22Ms9wdcJLV4oSeSzzv2FSwLT8NvvqNeNc4YArshbnVDXKDEUrfhhueh
|
||||
Ay2ZK58clpkaDVYg2hckgQKBgG3KuhtSI/YE4fwXN9yez7A2XNGPZem/IGqWo9lu
|
||||
PGJCrXqT2IqPLW82gB083r6jo+CUhonTxqqb82tA7g4PUvqvQ5Dmnk1NMKYe255K
|
||||
gp3HUO8GF2EWFIak5Hcr6oOLuDi6cjh3/euTk7ld8fYsTD0mzEOjiQhWW1p5X6bT
|
||||
LLp/AoGAHvkxA1NM1HJ3myAREbwNXxRy/nhNt4mwMkZ6hPQsW/Eg/3r7j6MJOFrm
|
||||
U8AJJjDGKe6nlXhhnMoQfJzAc0cYNgjktmJXW27fHGIwt/2QwYNFHPK3s7HTrfH6
|
||||
7T4XKT3yGeeeyC2soKJQPlGB+ETdIUnXa7eo9KVWtMTgISyx1Qk=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
",
|
||||
samlServicePrivateKeySig => "-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAu4iToYAEmWQxgZDihGVzMMql1elPn37domWcvXeU2E4yt2hh
|
||||
5jkQHiFjgodfOlNeRIw5QJVlUBwr+CQvbaKRFXd7BrOhQIDC0TZPRVB0XHarUtsC
|
||||
uDekN4/2GKSzHsoToKUVPWq9thsuek3xkpsJGZNX7bglfEc9+QQpYTqN1rkdN1PV
|
||||
U0epNMokFFGho5pLRqLUV5+I/QXAL49jfTjaSxsp4UndTI8/+mGSRSq+nrT2zyQR
|
||||
M/vkj5vR9ZVz67HO/+Wk3Mx6RAwkVcMdgMAqCq8odmbI0yCRZiTL9ybKWRKqWJoK
|
||||
J0p5+Q2fPEBPupQZR09Jt/JPuLVSsGfCxi9NqwIDAQABAoIBABE0Cjb6g3F+23vD
|
||||
SsRSeiqzrFrfOEqtXK+VGrfWzHS7V7Ozg6eW/H+HGJXUzUuQcklfg7EFA3JB41a0
|
||||
GxW3oA+UElkfCV/dcAG5NbRqGQKScEz9glZb5FikgDLqiPP+HabS/gvQSu71t2HI
|
||||
3KxSRJdwCNTp26Z28pxxYUpmELTtxd9vlHjffit2Mnt2uc8hOtFHdNavfYwvYH7o
|
||||
bmlckp7b/JVOy2Yy21O94ZWkE498jXyn71Gr+V1cnJ0RrmYbhQqIvFpFHj98Pf4O
|
||||
if3c4YmBcZ4t7PUsZUYF3ooWt8k/mdigQC3D6p80OKe+wUTYKcCN0ZdFbiURv9pg
|
||||
CsqLh+ECgYEA9vA+9QfzvXC7S5yXgTkuRiusPlNye/AiyA/0oGjmjFZ1YNsT7awH
|
||||
6BjW6WE+rS4elKJu1GaefM/cDguH4ZmJc+eKgi4LDCqYw9rr9les3aneBc8demd3
|
||||
O/Ej1Pud1QxXArBNfBYo08vEqwST9P89clJC5090U6bGK2E0rTVu1w0CgYEAwmpG
|
||||
9LbOFeGCPmwX7Avuk7tQQfRSV6q9TFZo+HxDfKYvxec846l1vBenY2rrgYhtolYJ
|
||||
YS795LYgbSWRxGfgr1GuIbP5GsjHy6/1o6bS8M++GJ7KHArb0QLAYyQweqqb164A
|
||||
NvHJkveueWnxzeOlD9j2fcjEnBHwTnqjG+17CZcCgYEAqMXawa4FsNxzpmIISpHC
|
||||
RsNindZ60Kp3mzUMhPYtXI1a/C+/lxmU7dTMTgXgyIxU6lF6XkEk4TlPtWm8HTzK
|
||||
7SS7Te4aLt6OOo5N57hUtct7q4y7IQXGQHm3e8HdRdeBQJ0u2Dhs/xSt/hTK6w/n
|
||||
91Kx11Y+s02w88UkM53pe6ECgYAF/UYwVc1liSv9BlF6WSfBb1zam09KGh1405Sq
|
||||
SxG9LlV8cFJE5TyWTdg/TNTyiaRvAt2JG+yAdkfrdOPXvCeE3yxRJ30+IP9evA4C
|
||||
O6p19sBxe7rYQFFjUAVjSIMh1E22yEqDZtGB8JV0chob8K5uHY4CdAPylu7jTA3o
|
||||
V1maAwKBgQCSGQ3yzsk4EGN2xd/JdgGDzhKyTZTQKMWYqQcsYxRAQ7Paj7u+Wkgv
|
||||
dBeKcI0HwgpLy5ZohSd2erqieIsW0pEbJWCmos4IcO8tgNfEOa5WXYdyLbj5tFwt
|
||||
ctu4/BJdijqfpMAtG8pv6k09gYjfASVytXmydGcs/0rVKYCRQA8Tow==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
",
|
||||
samlServicePublicKeyEnc => "-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsRaod2RZ8hMFBl+Vhsnh
|
||||
yPM8l/Fj1obnBxfQIaWuHFIFfXiGe/CYHuZ5QJQLnZxHMJX6LL3Sh+Usog3p0jpi
|
||||
jpcg0QgfBSEkfopKTgReYN8DiDIll0rV1XdTni7E85Nd1YyNy3ui/ZD+UShWwqu6
|
||||
jLVLR+QUm+/1LIKYb3OCBTvOlY7xHoP6NSU1+Mr+YzGBUacdO2vnNxe/PQhxIeP1
|
||||
zO0njuqGHkwEpy8rUWRZbbDn31TmKjqlhgtsz5HPhbRaYEExhyepKgBiNz+RyxtY
|
||||
XVhuG8OrWQDoS5gYHSjdw1CTJyixeJwyoqA9RGYguG5nh9zndi3LWAh7Z0lx+tIz
|
||||
+wIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
",
|
||||
samlSPSSODescriptorAuthnRequestsSigned => 1,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub sp2 {
|
||||
return LLNG::Manager::Test->new( {
|
||||
ini => {
|
||||
logLevel => $debug,
|
||||
domain => 'sp2.com',
|
||||
portal => 'http://auth.sp2.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 => 'redirect',
|
||||
samlIDPMetaDataOptionsSLOBinding => 'redirect',
|
||||
samlIDPMetaDataOptionsSignSSOMessage => 1,
|
||||
samlIDPMetaDataOptionsSignSLOMessage => 1,
|
||||
samlIDPMetaDataOptionsCheckSSOMessageSignature => 1,
|
||||
samlIDPMetaDataOptionsCheckSLOMessageSignature => 1,
|
||||
samlIDPMetaDataOptionsForceUTF8 => 1,
|
||||
}
|
||||
},
|
||||
samlIDPMetaDataExportedAttributes => {
|
||||
idp => {
|
||||
"uid" => "0;uid;;",
|
||||
"cn" => "1;cn;;",
|
||||
},
|
||||
},
|
||||
samlIDPMetaDataXML => {
|
||||
idp => {
|
||||
samlIDPMetaDataXML =>
|
||||
samlIDPMetaDataXML( 'idp', 'HTTP-Redirect' )
|
||||
}
|
||||
},
|
||||
samlOrganizationDisplayName => "SP",
|
||||
samlOrganizationName => "SP",
|
||||
samlOrganizationURL => "http://www.sp2.com",
|
||||
samlServicePublicKeySig => "-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu4iToYAEmWQxgZDihGVz
|
||||
MMql1elPn37domWcvXeU2E4yt2hh5jkQHiFjgodfOlNeRIw5QJVlUBwr+CQvbaKR
|
||||
FXd7BrOhQIDC0TZPRVB0XHarUtsCuDekN4/2GKSzHsoToKUVPWq9thsuek3xkpsJ
|
||||
GZNX7bglfEc9+QQpYTqN1rkdN1PVU0epNMokFFGho5pLRqLUV5+I/QXAL49jfTja
|
||||
Sxsp4UndTI8/+mGSRSq+nrT2zyQRM/vkj5vR9ZVz67HO/+Wk3Mx6RAwkVcMdgMAq
|
||||
Cq8odmbI0yCRZiTL9ybKWRKqWJoKJ0p5+Q2fPEBPupQZR09Jt/JPuLVSsGfCxi9N
|
||||
qwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
",
|
||||
samlServicePrivateKeyEnc => "-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAsRaod2RZ8hMFBl+VhsnhyPM8l/Fj1obnBxfQIaWuHFIFfXiG
|
||||
e/CYHuZ5QJQLnZxHMJX6LL3Sh+Usog3p0jpijpcg0QgfBSEkfopKTgReYN8DiDIl
|
||||
l0rV1XdTni7E85Nd1YyNy3ui/ZD+UShWwqu6jLVLR+QUm+/1LIKYb3OCBTvOlY7x
|
||||
HoP6NSU1+Mr+YzGBUacdO2vnNxe/PQhxIeP1zO0njuqGHkwEpy8rUWRZbbDn31Tm
|
||||
Kjqlhgtsz5HPhbRaYEExhyepKgBiNz+RyxtYXVhuG8OrWQDoS5gYHSjdw1CTJyix
|
||||
eJwyoqA9RGYguG5nh9zndi3LWAh7Z0lx+tIz+wIDAQABAoIBAEkZrk8iiJKJ0WAx
|
||||
IrsyKNbXuWKLTYgnxcRCyzKofrfID+YcU39j8JeI0fKbajQUZ7qhnlTLwtU//+2h
|
||||
SqzyVu6/add/v7ZRWQw3L7cGzKK2THHzKVtLk/t7N3QroDdf1LMrQvkFP2HmcWS0
|
||||
/yN62hXtXHb/qpY4Nn+6JQyUpM5dkv8S/QjDl2NTdyWrXKzWp+4I3QLQ20f4zym+
|
||||
ir7RennziMc0HlQNcTjGAUbFULtdqEfSFWhNK7UjiRY+S0XV2xJIbGjnxUQH62fS
|
||||
w1ZzYsF7sBtoSckvfL4WfGbylhOVnliU05RLU2c67PRjj1Gskoslq1Ow/3DHR7rI
|
||||
BSBpV8ECgYEA1eHfcog7xQGDkW+cshJtFPFx+9MegB58gFW1rl0rn+tfbexvoSEA
|
||||
7G7EOTyaU6OAI+8StiRT6AYTgEU7PMM9zDykdGIWj3h0OpHGA86xhEiiaaM2DDRv
|
||||
/DEKRVlEdmRLLLY28pJVHOMYomia3mb2VKZGg2VfGtSfjg1GXD3I8OECgYEA0/X0
|
||||
U55KjZ1JQTPUgFc1WK1NxX9MaH+NcpDaolEUy3Qf3QTbfws+a9K3vwCn7EpQhrfs
|
||||
I6RVUtwFdCyfl/jzBY9Gykkg03sMgW7Qw2SCCsSt05M+jDtBbNJ7esP6PAeKFvXZ
|
||||
ZWhdeiAa4kM/P6gtvZXQ4tY4LkSbcd6b0SzzFFsCgYBjMsusFzuBd95JyfZnMNye
|
||||
5gzzu0teKMWd0CLfqB7foQ81sH9lwCTpg8ZGtbDuMdrwz6ViDR9NceQBjhqXaAZ1
|
||||
f3rW79d+22Ms9wdcJLV4oSeSzzv2FSwLT8NvvqNeNc4YArshbnVDXKDEUrfhhueh
|
||||
Ay2ZK58clpkaDVYg2hckgQKBgG3KuhtSI/YE4fwXN9yez7A2XNGPZem/IGqWo9lu
|
||||
PGJCrXqT2IqPLW82gB083r6jo+CUhonTxqqb82tA7g4PUvqvQ5Dmnk1NMKYe255K
|
||||
gp3HUO8GF2EWFIak5Hcr6oOLuDi6cjh3/euTk7ld8fYsTD0mzEOjiQhWW1p5X6bT
|
||||
LLp/AoGAHvkxA1NM1HJ3myAREbwNXxRy/nhNt4mwMkZ6hPQsW/Eg/3r7j6MJOFrm
|
||||
U8AJJjDGKe6nlXhhnMoQfJzAc0cYNgjktmJXW27fHGIwt/2QwYNFHPK3s7HTrfH6
|
||||
7T4XKT3yGeeeyC2soKJQPlGB+ETdIUnXa7eo9KVWtMTgISyx1Qk=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
",
|
||||
samlServicePrivateKeySig => "-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAu4iToYAEmWQxgZDihGVzMMql1elPn37domWcvXeU2E4yt2hh
|
||||
5jkQHiFjgodfOlNeRIw5QJVlUBwr+CQvbaKRFXd7BrOhQIDC0TZPRVB0XHarUtsC
|
||||
uDekN4/2GKSzHsoToKUVPWq9thsuek3xkpsJGZNX7bglfEc9+QQpYTqN1rkdN1PV
|
||||
U0epNMokFFGho5pLRqLUV5+I/QXAL49jfTjaSxsp4UndTI8/+mGSRSq+nrT2zyQR
|
||||
M/vkj5vR9ZVz67HO/+Wk3Mx6RAwkVcMdgMAqCq8odmbI0yCRZiTL9ybKWRKqWJoK
|
||||
J0p5+Q2fPEBPupQZR09Jt/JPuLVSsGfCxi9NqwIDAQABAoIBABE0Cjb6g3F+23vD
|
||||
SsRSeiqzrFrfOEqtXK+VGrfWzHS7V7Ozg6eW/H+HGJXUzUuQcklfg7EFA3JB41a0
|
||||
GxW3oA+UElkfCV/dcAG5NbRqGQKScEz9glZb5FikgDLqiPP+HabS/gvQSu71t2HI
|
||||
3KxSRJdwCNTp26Z28pxxYUpmELTtxd9vlHjffit2Mnt2uc8hOtFHdNavfYwvYH7o
|
||||
bmlckp7b/JVOy2Yy21O94ZWkE498jXyn71Gr+V1cnJ0RrmYbhQqIvFpFHj98Pf4O
|
||||
if3c4YmBcZ4t7PUsZUYF3ooWt8k/mdigQC3D6p80OKe+wUTYKcCN0ZdFbiURv9pg
|
||||
CsqLh+ECgYEA9vA+9QfzvXC7S5yXgTkuRiusPlNye/AiyA/0oGjmjFZ1YNsT7awH
|
||||
6BjW6WE+rS4elKJu1GaefM/cDguH4ZmJc+eKgi4LDCqYw9rr9les3aneBc8demd3
|
||||
O/Ej1Pud1QxXArBNfBYo08vEqwST9P89clJC5090U6bGK2E0rTVu1w0CgYEAwmpG
|
||||
9LbOFeGCPmwX7Avuk7tQQfRSV6q9TFZo+HxDfKYvxec846l1vBenY2rrgYhtolYJ
|
||||
YS795LYgbSWRxGfgr1GuIbP5GsjHy6/1o6bS8M++GJ7KHArb0QLAYyQweqqb164A
|
||||
NvHJkveueWnxzeOlD9j2fcjEnBHwTnqjG+17CZcCgYEAqMXawa4FsNxzpmIISpHC
|
||||
RsNindZ60Kp3mzUMhPYtXI1a/C+/lxmU7dTMTgXgyIxU6lF6XkEk4TlPtWm8HTzK
|
||||
7SS7Te4aLt6OOo5N57hUtct7q4y7IQXGQHm3e8HdRdeBQJ0u2Dhs/xSt/hTK6w/n
|
||||
91Kx11Y+s02w88UkM53pe6ECgYAF/UYwVc1liSv9BlF6WSfBb1zam09KGh1405Sq
|
||||
SxG9LlV8cFJE5TyWTdg/TNTyiaRvAt2JG+yAdkfrdOPXvCeE3yxRJ30+IP9evA4C
|
||||
O6p19sBxe7rYQFFjUAVjSIMh1E22yEqDZtGB8JV0chob8K5uHY4CdAPylu7jTA3o
|
||||
V1maAwKBgQCSGQ3yzsk4EGN2xd/JdgGDzhKyTZTQKMWYqQcsYxRAQ7Paj7u+Wkgv
|
||||
dBeKcI0HwgpLy5ZohSd2erqieIsW0pEbJWCmos4IcO8tgNfEOa5WXYdyLbj5tFwt
|
||||
ctu4/BJdijqfpMAtG8pv6k09gYjfASVytXmydGcs/0rVKYCRQA8Tow==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
",
|
||||
samlServicePublicKeyEnc => "-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsRaod2RZ8hMFBl+Vhsnh
|
||||
yPM8l/Fj1obnBxfQIaWuHFIFfXiGe/CYHuZ5QJQLnZxHMJX6LL3Sh+Usog3p0jpi
|
||||
jpcg0QgfBSEkfopKTgReYN8DiDIll0rV1XdTni7E85Nd1YyNy3ui/ZD+UShWwqu6
|
||||
jLVLR+QUm+/1LIKYb3OCBTvOlY7xHoP6NSU1+Mr+YzGBUacdO2vnNxe/PQhxIeP1
|
||||
zO0njuqGHkwEpy8rUWRZbbDn31TmKjqlhgtsz5HPhbRaYEExhyepKgBiNz+RyxtY
|
||||
XVhuG8OrWQDoS5gYHSjdw1CTJyixeJwyoqA9RGYguG5nh9zndi3LWAh7Z0lx+tIz
|
||||
+wIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
",
|
||||
samlSPSSODescriptorAuthnRequestsSigned => 1,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
|
@ -72,7 +72,7 @@ sub iniCmb {
|
|||
my $res = LLNG::Manager::Test->new( {
|
||||
ini => {
|
||||
logLevel => 'error',
|
||||
requireToken => 1,
|
||||
requireToken => '$ipAddr eq "127.0.0.1"',
|
||||
useSafeJail => 1,
|
||||
authentication => 'Combination',
|
||||
userDB => 'Same',
|
||||
|
|
|
@ -31,7 +31,7 @@ SKIP: {
|
|||
userDB => 'Same',
|
||||
passwordDB => 'Demo',
|
||||
captcha_mail_enabled => 0,
|
||||
requireToken => 1,
|
||||
requireToken => '$ipAddr eq "127.0.0.1"',
|
||||
portalDisplayResetPassword => 1,
|
||||
portalMainLogo => 'common/logos/logo_llng_old.png',
|
||||
}
|
||||
|
|
|
@ -124,6 +124,7 @@ count(1);
|
|||
# Request with good VH & user
|
||||
$query =~
|
||||
s/url=http%3A%2F%2Ftry.example.com/url=http%3A%2F%2Ftest1.example.com/;
|
||||
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/checkuser',
|
||||
|
@ -140,8 +141,65 @@ count(1);
|
|||
expectForm( $res, undef, '/checkuser', 'user', 'url' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
||||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok( $res->[2]->[0] =~ m%value="http://test1.example.com/"%, 'Found well formatted url' )
|
||||
or explain( $res->[2]->[0], 'Well formatted url' );
|
||||
count(2);
|
||||
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
||||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
or explain( $res->[2]->[0], 'trspan="headers"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="groups_sso">%,
|
||||
'Found trspan="groups_sso"' )
|
||||
or explain( $res->[2]->[0], 'trspan="groups_sso"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">rtyler</td>%, 'Found rtyler' )
|
||||
or explain( $res->[2]->[0], 'Header Value: rtyler' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su</td>%, 'Found su' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
count(11);
|
||||
|
||||
# Request with short VH url & user
|
||||
$query =~
|
||||
s/url=http%3A%2F%2Ftest1.example.com/url=http%3A%2F%2Ftest1:1234/;
|
||||
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/checkuser',
|
||||
IO::String->new($query),
|
||||
cookie => "lemonldap=$id",
|
||||
length => length($query),
|
||||
accept => 'text/html',
|
||||
),
|
||||
'POST checkuser'
|
||||
);
|
||||
count(1);
|
||||
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $res, undef, '/checkuser', 'user', 'url' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
||||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok( $res->[2]->[0] =~ m%value="http://test1.example.com:1234/"%, 'Found well formatted url' )
|
||||
or explain( $res->[2]->[0], 'Well formatted url' );
|
||||
count(2);
|
||||
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
||||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok(
|
||||
|
|
|
@ -170,7 +170,7 @@ to test content _(to launch a `expectForm()` for example)_.
|
|||
Same as `_get` except that a body is required. $body must be a file handle.
|
||||
Example with IO::String:
|
||||
|
||||
ok(
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new('user=dwho&password=dwho'),
|
||||
|
|
|
@ -660,7 +660,7 @@ sub _get {
|
|||
Same as C<_get> except that a body is required. $body must be a file handle.
|
||||
Example with IO::String:
|
||||
|
||||
ok(
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new('user=dwho&password=dwho'),
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
# Main package
|
||||
#==============================================================================
|
||||
Name: lemonldap-ng
|
||||
Version: 2.0.2
|
||||
Version: 2.0.3
|
||||
Release: %{?pre_release:0.}1%{?pre_release:.%{pre_release}}%{?dist}
|
||||
Summary: LemonLDAP-NG WebSSO
|
||||
License: GPLv2+
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
use LWP::UserAgent;
|
||||
use JSON;
|
||||
|
||||
my $milestone = '2.0.2';
|
||||
my $milestone = '2.0.3';
|
||||
my @cat = ( 'Bug', 'New feature', 'Improvement' );
|
||||
|
||||
open F, "$ENV{HOME}/.ow2-token" or die "Unable to get OW2 token ($!)";
|
||||
|
|
|
@ -78,8 +78,7 @@ for ( my $i = 0 ; $i < NB ; $i++ ) {
|
|||
|
||||
print "Result
|
||||
+-----+-----------+----------+---------+-----------------------------------------+
|
||||
| Req | Auth form | Post req | Menu | 5 access to test1.example.com
|
||||
|
|
||||
| Req | Auth form | Post req | Menu | 5 access to test1.example.com |
|
||||
+-----+-----------+----------+---------+-----------------------------------------+
|
||||
";
|
||||
|
||||
|
|
Loading…
Reference in New Issue