Commit 01b5951b authored by Xavier Guimard's avatar Xavier Guimard

Merge branch 'v2.0'

parents 47986831 2159957c
......@@ -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 \
......
......@@ -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\""
......
......@@ -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\""
......
{"_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}
\ No newline at end of file
{"_session_kind":"Persistent","_loginHistory":{"successLogin":[{"ipAddr":"127.0.0.1","_utime":1548016089}]},"_2fDevices":"[]","_session_id":"5efe8af397fc3577e05b483aca964f1b","_session_uid":"dwho","_updateTime":"20190120221550","_utime":1548016089}
{"_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();
});
});
});
\ No newline at end of file
});
......@@ -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; });
\ No newline at end of file
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;
}
})();
\ No newline at end of file
})();
......@@ -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">
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -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) {