Merge branch 'v2.0' into dcoutadeur/lemonldap-ng-certificate-reset

This commit is contained in:
Clément OUDOT 2019-12-21 16:19:49 +01:00
commit 458d353af8
39 changed files with 513 additions and 164 deletions

View File

@ -4,11 +4,11 @@
describe('00 Lemonldap::NG', function() {
describe('Auth mechanism', function() {
it('Portal should display 11 lang flags', function() {
it('Portal should display 12 lang flags', function() {
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
browser.sleep(500);
browser.driver.findElements(by.className('langicon')).then(function(elems) {
expect(elems.length).toEqual(11);
expect(elems.length).toEqual(12);
});
browser.sleep(500);
browser.driver.findElement(by.xpath("//img[@title='en']")).click();
@ -67,7 +67,7 @@ describe('00 Lemonldap::NG', function() {
browser.driver.findElement(by.xpath("//input[@name='checkLogins']")).click();
browser.driver.findElement(by.xpath("//button[@type='submit']")).click();
expect(browser.driver.findElement(by.css('[trmsg="5"]')).getText()).toEqual('Identifiant ou mot de passe incorrect');
browser.driver.findElement(by.css('[trspan="goToPortal"]')).click();
//browser.driver.findElement(by.css('[trspan="goToPortal"]')).click();
// Login attempt
browser.driver.findElement(by.xpath("//input[@name='user']")).sendKeys('dwho');
@ -77,7 +77,7 @@ describe('00 Lemonldap::NG', function() {
// Change lang
browser.driver.findElement(by.xpath("//img[@title='de']")).click();
expect(browser.driver.findElement(by.css('[trspan="info"]')).getText()).toEqual("Information");
//expect(browser.driver.findElement(by.css('[trspan="info"]')).getText()).toEqual("Information");
});
it('should display history', function() {
// Three entries
@ -85,11 +85,10 @@ describe('00 Lemonldap::NG', function() {
expect(elems.length).toEqual(3);
});
// Expect history with two logins and one failed login
browser.driver.findElements(by.xpath('//form/div/div/h3')).then(function(elems) {
expect(elems.length).toEqual(3);
expect(elems[0].getText()).toEqual('Information');
expect(elems[1].getText()).toEqual('Letzte Anmeldungen');
expect(elems[2].getText()).toEqual('Letzte fehlgeschlagene Anmeldungen');
browser.driver.findElements(by.xpath("//div[@id='loginHistory']/div/div/h4")).then(function(elems) {
expect(elems.length).toEqual(2);
expect(elems[0].getText()).toEqual('Letzte Anmeldungen');
expect(elems[1].getText()).toEqual('Letzte fehlgeschlagene Anmeldungen');
});
browser.driver.findElements(by.xpath('//table/thead/tr/th')).then(function(elems) {
expect(elems.length).toEqual(5);
@ -105,10 +104,10 @@ describe('00 Lemonldap::NG', function() {
expect(elems[6].getText()).toEqual('Benutzername oder Passwort nicht korrekt');
});
expect(browser.driver.findElement(by.css('[trspan="PE5"]')).getText()).toEqual('Benutzername oder Passwort nicht korrekt');
expect(browser.driver.findElement(by.id('timer')).getText()).toMatch(/^Du wirst in \d{2} Sekunden umgeleitet$/);
browser.driver.findElement(by.xpath("//button[@type='reset']")).click();
expect(browser.driver.findElement(by.id('timer')).isDisplayed()).toEqual(false);
browser.driver.findElement(by.xpath("//button[@type='submit']")).click();
//expect(browser.driver.findElement(by.id('timer')).getText()).toMatch(/^Du wirst in \d{2} Sekunden umgeleitet$/);
//browser.driver.findElement(by.xpath("//button[@type='reset']")).click();
//expect(browser.driver.findElement(by.id('timer')).isDisplayed()).toEqual(false);
//browser.driver.findElement(by.xpath("//button[@type='submit']")).click();
});
});
});

View File

@ -1,4 +1,4 @@
.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35)
.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35)
.\"
.\" Standard preamble:
.\" ========================================================================
@ -54,16 +54,20 @@
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.if !\nF .nr F 0
.if \nF>0 \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
@ -129,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "llng-fastcgi-server 8"
.TH llng-fastcgi-server 8 "2019-11-08" "perl v5.26.1" "User Contributed Perl Documentation"
.TH llng-fastcgi-server 8 "2019-12-11" "perl v5.28.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l

View File

@ -23,7 +23,7 @@ use constant HANDLERSECTION => "handler";
use constant MANAGERSECTION => "manager";
use constant SESSIONSEXPLORERSECTION => "sessionsExplorer";
use constant APPLYSECTION => "apply";
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|facebook|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|macro)s|o(?:idc(?:RPMetaData(?:(?:Option(?:sExtraClaim)?|ExportedVar|Macro)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node)|S(?:erviceMetaDataAuthnContext|torageOptions))|penIdExportedVars)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option|Macro)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|c(?:as(?:A(?:ppMetaData(?:(?:ExportedVar|Option|Macro)s|Node)|ttributes)|S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions))|(?:ustom(?:Plugins|Add)Param|ombModule)s)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|a(?:ut(?:hChoiceMod|oSigninR)ules|pplicationList)|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|facebook|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|macro)s|o(?:idc(?:S(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|RPMetaData(?:(?:Option(?:sExtraClaim)?|ExportedVar|Macro)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node))|penIdExportedVars)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option|Macro)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|c(?:as(?:A(?:ppMetaData(?:(?:ExportedVar|Option|Macro)s|Node)|ttributes)|S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions))|(?:ustom(?:Plugins|Add)Param|ombModule)s)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|a(?:ut(?:hChoiceMod|oSigninR)ules|pplicationList)|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|ingle(?:Session(?:UserByIP)?|(?:UserBy)?IP)|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|kipRenewConfirmation|fRemovedUseNotif|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|AllowOffline|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:setPassword|gister)|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|RequireOldPassword|ForceAuthn|AntiFrame)|roxyUseSoap)|c(?:a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:User(?:Display(?:PersistentInfo|EmptyValues))?|State|XSS)|o(?:ntextSwitchingStopWithLogout|rsEnabled)|da)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?)?|y(?:Deleted|Other))|AjaxHook)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|re(?:st(?:(?:Session|Config)Server|ExportSecretKeys)|freshSessions)|d(?:isablePersistentStorage|biDynamicHashEnabled|ontCompactConf)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|br(?:owsersDontStorePassword|uteForceProtection)|(?:(?:globalLogout|active)Tim|wsdlServ)er|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs))$/;
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );

View File

@ -54,7 +54,7 @@ sub defaultValues {
'cspConnect' => '\'self\'',
'cspDefault' => '\'self\'',
'cspFont' => '\'self\'',
'cspFormAction' => '\'self\'',
'cspFormAction' => '*',
'cspImg' => '\'self\' data:',
'cspScript' => '\'self\'',
'cspStyle' => '\'self\'',

View File

@ -22,7 +22,7 @@ our $specialNodeHash = {
};
our $doubleHashKeys = 'issuerDBGetParameters';
our $simpleHashKeys = '(?:(?:l(?:o(?:calSessionStorageOption|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|c(?:as(?:StorageOption|Attribute)|ustom(?:Plugins|Add)Param|ombModule)|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|(?:(?:d(?:emo|bi)|facebook|webID)E|e)xportedVar|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|p(?:ersistentStorageOption|ortalSkinRule)|macro)s|o(?:idcS(?:erviceMetaDataAuthnContext|torageOptions)|penIdExportedVars)|s(?:(?:amlStorageOption|laveExportedVar)s|essionDataToRemember|fExtra)|a(?:ut(?:hChoiceMod|oSigninR)ules|pplicationList)|S(?:MTPTLSOpts|SLVarIf))';
our $simpleHashKeys = '(?:(?:l(?:o(?:calSessionStorageOption|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|c(?:as(?:StorageOption|Attribute)|ustom(?:Plugins|Add)Param|ombModule)|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|(?:(?:d(?:emo|bi)|facebook|webID)E|e)xportedVar|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|p(?:ersistentStorageOption|ortalSkinRule)|macro)s|o(?:idcS(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|penIdExportedVars)|s(?:(?:amlStorageOption|laveExportedVar)s|essionDataToRemember|fExtra)|a(?:ut(?:hChoiceMod|oSigninR)ules|pplicationList)|S(?:MTPTLSOpts|SLVarIf))';
our $specialNodeKeys = '(?:(?:(?:saml(?:ID|S)|oidc[OR])P|cas(?:App|Srv))MetaDataNode|virtualHost)s';
our $casAppMetaDataNodeKeys = 'casAppMetaData(?:Options(?:UserAttribut|Servic|Rul)e|(?:ExportedVar|Macro)s)';
our $casSrvMetaDataNodeKeys = 'casSrvMetaData(?:Options(?:ProxiedServices|DisplayName|SortNumber|Gateway|Renew|Icon|Url)|ExportedVars)';
@ -68,6 +68,6 @@ our $issuerParameters = {
issuerOptions => [qw(issuersTimeout)],
};
our $samlServiceParameters = [qw(samlEntityID samlServicePrivateKeySig samlServicePrivateKeySigPwd samlServicePublicKeySig samlServicePrivateKeyEnc samlServicePrivateKeyEncPwd samlServicePublicKeyEnc samlServiceUseCertificateInResponse samlServiceSignatureMethod samlNameIDFormatMapEmail samlNameIDFormatMapX509 samlNameIDFormatMapWindows samlNameIDFormatMapKerberos samlAuthnContextMapPassword samlAuthnContextMapPasswordProtectedTransport samlAuthnContextMapTLSClient samlAuthnContextMapKerberos samlOrganizationDisplayName samlOrganizationName samlOrganizationURL samlSPSSODescriptorAuthnRequestsSigned samlSPSSODescriptorWantAssertionsSigned samlSPSSODescriptorSingleLogoutServiceHTTPRedirect samlSPSSODescriptorSingleLogoutServiceHTTPPost samlSPSSODescriptorSingleLogoutServiceSOAP samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact samlSPSSODescriptorAssertionConsumerServiceHTTPPost samlSPSSODescriptorArtifactResolutionServiceArtifact samlIDPSSODescriptorWantAuthnRequestsSigned samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect samlIDPSSODescriptorSingleSignOnServiceHTTPPost samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect samlIDPSSODescriptorSingleLogoutServiceHTTPPost samlIDPSSODescriptorSingleLogoutServiceSOAP samlIDPSSODescriptorArtifactResolutionServiceArtifact samlAttributeAuthorityDescriptorAttributeServiceSOAP samlMetadataForceUTF8 samlStorage samlStorageOptions samlRelayStateTimeout samlUseQueryStringSpecific samlCommonDomainCookieActivation samlCommonDomainCookieDomain samlCommonDomainCookieReader samlCommonDomainCookieWriter samlDiscoveryProtocolActivation samlDiscoveryProtocolURL samlDiscoveryProtocolPolicy samlDiscoveryProtocolIsPassive samlOverrideIDPEntityID)];
our $oidcServiceParameters = [qw(oidcServiceMetaDataIssuer oidcServiceMetaDataAuthorizeURI oidcServiceMetaDataTokenURI oidcServiceMetaDataUserInfoURI oidcServiceMetaDataJWKSURI oidcServiceMetaDataRegistrationURI oidcServiceMetaDataIntrospectionURI oidcServiceMetaDataEndSessionURI oidcServiceMetaDataCheckSessionURI oidcServiceMetaDataFrontChannelURI oidcServiceMetaDataBackChannelURI oidcServiceMetaDataAuthnContext oidcServicePrivateKeySig oidcServicePublicKeySig oidcServiceKeyIdSig oidcServiceAllowDynamicRegistration oidcServiceAllowAuthorizationCodeFlow oidcServiceAllowImplicitFlow oidcServiceAllowHybridFlow oidcServiceAuthorizationCodeExpiration oidcServiceAccessTokenExpiration oidcServiceIDTokenExpiration oidcServiceOfflineSessionExpiration oidcStorage oidcStorageOptions)];
our $oidcServiceParameters = [qw(oidcServiceMetaDataIssuer oidcServiceMetaDataAuthorizeURI oidcServiceMetaDataTokenURI oidcServiceMetaDataUserInfoURI oidcServiceMetaDataJWKSURI oidcServiceMetaDataRegistrationURI oidcServiceMetaDataIntrospectionURI oidcServiceMetaDataEndSessionURI oidcServiceMetaDataCheckSessionURI oidcServiceMetaDataFrontChannelURI oidcServiceMetaDataBackChannelURI oidcServiceMetaDataAuthnContext oidcServicePrivateKeySig oidcServicePublicKeySig oidcServiceKeyIdSig oidcServiceAllowDynamicRegistration oidcServiceAllowAuthorizationCodeFlow oidcServiceAllowImplicitFlow oidcServiceAllowHybridFlow oidcServiceAuthorizationCodeExpiration oidcServiceAccessTokenExpiration oidcServiceIDTokenExpiration oidcServiceOfflineSessionExpiration oidcStorage oidcStorageOptions oidcServiceDynamicRegistrationExportedVars oidcServiceDynamicRegistrationExtraClaims)];
1;

View File

@ -2,8 +2,9 @@ package Lemonldap::NG::Common::Notifications;
use strict;
use Mouse;
use JSON qw(to_json);
our $VERSION = '2.0.0';
our $VERSION = '2.0.7';
extends 'Lemonldap::NG::Common::Module';
@ -32,8 +33,14 @@ has notifField => (
sub getNotifications {
my ( $self, $uid ) = @_;
my $forAll = $self->get( $self->conf->{notificationWildcard} );
if ( $uid and $uid =~ /^_all(Pending|Existing)_$/ ) {
$self->logger->info("Retrieve all $1 notifications");
my $all = ( $1 eq 'Pending' ? $self->getAll() : $self->getExisting() );
$all = { map { $_ => to_json( $all->{$_} ) } keys %$all };
return ( $forAll ? { %$all, %$forAll } : $all );
}
my $forUser = $self->get($uid);
my $forAll = $self->get( $self->conf->{notificationWildcard} );
if ( $forUser and $forAll ) {
return { %$forUser, %$forAll };
}

View File

@ -11,7 +11,7 @@ use Time::Local;
use DBI;
use Encode;
our $VERSION = '2.0.2';
our $VERSION = '2.0.7';
extends 'Lemonldap::NG::Common::Notifications';
@ -93,9 +93,9 @@ sub get {
}
## @method hashref getAll()
# Return all messages not notified.
# Return all pending notifications.
# @return hashref where keys are internal reference and values are hashref with
# keys date, uid and ref.
# keys date, uid, ref and condition.
sub getAll {
my $self = shift;
$self->_execute( 'SELECT * FROM '
@ -114,6 +114,28 @@ sub getAll {
return $result;
}
## @method hashref getExisting()
# Return all notifications.
# @return hashref where keys are internal reference and values are hashref with
# keys date, uid, ref and condition.
sub getExisting {
my $self = shift;
$self->_execute( 'SELECT * FROM '
. $self->dbiTable
. ' ORDER BY date' );
my $result;
while ( my $h = $self->sth->fetchrow_hashref() ) {
$result->{"$h->{date}#$h->{uid}#$h->{ref}"} = {
date => $h->{date},
uid => $h->{uid},
ref => $h->{ref},
condition => $h->{condition}
};
}
$self->logger->warn( $self->sth->err() ) if ( $self->sth->err() );
return $result;
}
## @method boolean delete(string myref)
# Mark a notification as done.
# @param $myref identifier returned by get() or getAll()

View File

@ -9,7 +9,7 @@ use strict;
use Mouse;
use MIME::Base64;
our $VERSION = '2.0.6';
our $VERSION = '2.0.7';
extends 'Lemonldap::NG::Common::Notifications';
@ -58,9 +58,9 @@ sub get {
}
## @method hashref getAll()
# Return all messages not notified.
# Return all pending notifications.
# @return hashref where keys are internal reference and values are hashref with
# keys date, uid and ref.
# keys date, uid, ref ans condition.
sub getAll {
my $self = shift;
opendir D, $self->{dirName};
@ -82,6 +82,31 @@ sub getAll {
return \%h;
}
## @method hashref getExisting()
# Return all notifications.
# @return hashref where keys are internal reference and values are hashref with
# keys date, uid, ref and condition.
sub getExisting {
my $self = shift;
opendir D, $self->{dirName};
my @notif;
my $fns = $self->{fileNameSeparator};
@notif = grep /^\S*\.$ext$/, readdir(D);
my %h = map {
/^(\d{8})${fns}([^\s${fns}]+)${fns}([^\s${fns}]+)(?:${fns}([^\s${fns}]+))?\.(?:$ext|done)$/
? (
$_ => {
date => $1,
uid => $2,
ref => decode_base64($3),
condition => decode_base64( $4 // '' )
}
)
: ()
} @notif;
return \%h;
}
## @method boolean delete(string myref)
# Mark a notification as done.
# @param $myref identifier returned by get() or getAll()

View File

@ -13,7 +13,7 @@ use MIME::Base64;
use Net::LDAP;
use utf8;
our $VERSION = '2.0.0';
our $VERSION = '2.0.7';
extends 'Lemonldap::NG::Common::Notifications';
@ -78,15 +78,13 @@ sub get {
}
## @method hashref getAll()
# Return all messages not notified.
# Return all pending notifications.
# @return hashref where keys are internal reference and values are hashref with
# keys date, uid and ref.
# keys date, uid, ref and condition.
sub getAll {
my $self = shift;
my $self = shift;
my @entries = $self->_search(
'(&(objectClass=applicationProcess)(!(description={done}*)))');
my $result = {};
foreach my $entry (@entries) {
my @notifValues = $entry->get_value('description');
@ -102,10 +100,34 @@ sub getAll {
ref => $f->{ref},
cond => $f->{condition},
};
}
return $result;
}
## @method hashref getExisting()
# Return all notifications.
# @return hashref where keys are internal reference and values are hashref with
# keys date, uid, ref and condition.
sub getExisting {
my $self = shift;
my @entries = $self->_search('objectClass=applicationProcess');
my $result = {};
foreach my $entry (@entries) {
my @notifValues = $entry->get_value('description');
my $f = {};
foreach (@notifValues) {
my ( $k, $v ) = ( $_ =~ /\{(.*?)\}(.*)/smg );
$v = decodeLdapValue($v);
$f->{$k} = $v;
}
$result->{"$f->{date}#$f->{uid}#$f->{ref}"} = {
date => $f->{date},
uid => $f->{uid},
ref => $f->{ref},
cond => $f->{condition},
};
}
return $result;
}
## @method boolean delete(string myref)

View File

@ -1049,7 +1049,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'type' => 'text'
},
'cspFormAction' => {
'default' => '\'self\'',
'default' => '*',
'type' => 'text'
},
'cspImg' => {
@ -2204,6 +2204,12 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
'default' => 60,
'type' => 'int'
},
'oidcServiceDynamicRegistrationExportedVars' => {
'type' => 'keyTextContainer'
},
'oidcServiceDynamicRegistrationExtraClaims' => {
'type' => 'keyTextContainer'
},
'oidcServiceIDTokenExpiration' => {
'default' => 3600,
'type' => 'int'

View File

@ -835,7 +835,7 @@ sub attributes {
},
cspFormAction => {
type => 'text',
default => "'self'",
default => "*",
documentation =>
'Form action destination for Content-Security-Policy',
},
@ -2193,9 +2193,9 @@ sub attributes {
type => 'keyTextContainer',
help =>
'exportedvars.html#extend_variables_using_macros_and_groups',
test => {
keyTest => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
keyMsgFail => '__badMacroName__',
test => {
keyTest => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
keyMsgFail => '__badMacroName__',
test => sub { return perlExpr(@_) },
},
default => {},
@ -2804,9 +2804,9 @@ sub attributes {
type => 'keyTextContainer',
help =>
'exportedvars.html#extend_variables_using_macros_and_groups',
test => {
keyTest => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
keyMsgFail => '__badMacroName__',
test => {
keyTest => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
keyMsgFail => '__badMacroName__',
test => sub { return perlExpr(@_) },
},
default => {},
@ -3736,6 +3736,16 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
default => 3600,
documentation => 'OpenID Connect global access token TTL',
},
oidcServiceDynamicRegistrationExportedVars => {
type => 'keyTextContainer',
documentation =>
'OpenID Connect exported variables for dynamic registration',
},
oidcServiceDynamicRegistrationExtraClaims => {
type => 'keyTextContainer',
documentation =>
'OpenID Connect extra claims for dynamic registration',
},
oidcServiceIDTokenExpiration => {
type => 'int',
default => 3600,
@ -3907,9 +3917,9 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
type => 'keyTextContainer',
help =>
'exportedvars.html#extend_variables_using_macros_and_groups',
test => {
keyTest => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
keyMsgFail => '__badMacroName__',
test => {
keyTest => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
keyMsgFail => '__badMacroName__',
test => sub { return perlExpr(@_) },
},
default => {},

View File

@ -1217,6 +1217,8 @@ sub tree {
title => "oidcServiceMetaDataSessions",
nodes => [ 'oidcStorage', 'oidcStorageOptions', ],
},
'oidcServiceDynamicRegistrationExportedVars',
'oidcServiceDynamicRegistrationExtraClaims',
]
},
'oidcOPMetaDataNodes',

View File

@ -4,7 +4,7 @@ use utf8;
use Lemonldap::NG::Common::Regexp;
use Lemonldap::NG::Handler::Main;
our $VERSION = '2.0.6';
our $VERSION = '2.0.7';
## @method hashref tests(hashref conf)
# Return a hash ref where keys are the names of the tests and values
@ -719,6 +719,26 @@ sub tests {
return 1;
},
# OIDC redirect URI must not be empty
oidcRPRedirectURINotEmpty => sub {
return 1
unless ( $conf->{oidcRPMetaDataOptions}
and %{ $conf->{oidcRPMetaDataOptions} } );
my @msg;
my $res = 1;
foreach my $oidcRpId ( keys %{ $conf->{oidcRPMetaDataOptions} } ) {
unless ( $conf->{oidcRPMetaDataOptions}->{$oidcRpId}
->{oidcRPMetaDataOptionsRedirectUris} )
{
push @msg,
"$oidcRpId OpenID Connect RP has no redirect URI defined";
$res = 0;
next;
}
}
return ( $res, join( ', ', @msg ) );
},
};
}

View File

@ -200,7 +200,7 @@ sub notifications {
result => 1,
count => $count,
values => $res,
total => $total
total => $total
}
);
}
@ -220,8 +220,15 @@ sub notifications {
@r = sort { $a->{$f} cmp $b->{$f} } @r;
}
}
return $self->sendJSONresponse( $req,
{ result => 1, count => scalar(@r), values => \@r, total => $total } );
return $self->sendJSONresponse(
$req,
{
result => 1,
count => scalar(@r),
values => \@r,
total => $total
}
);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -615,6 +615,8 @@
"oidcServiceKeyIdSig":"توقيع على هوية المفتاح ",
"oidcServiceAuthorizationCodeExpiration":"Authorization Code expiration",
"oidcServiceAccessTokenExpiration":"انتهاء صلاحية التوكن",
"oidcServiceDynamicRegistrationExportedVars":"Exported vars for dynamic registration",
"oidcServiceDynamicRegistrationExtraClaims":"Extra claims for dynamic registration",
"oidcServiceIDTokenExpiration":" انتهاء صلاحية تعريف التوكن",
"oidcServiceOfflineSessionExpiration":"Offline session expiration",
"oidcStorage":"اسم وحدة الجلسات",

View File

@ -615,6 +615,8 @@
"oidcServiceKeyIdSig":"Signing key ID",
"oidcServiceAuthorizationCodeExpiration":"Authorization Code expiration",
"oidcServiceAccessTokenExpiration":"Access Token expiration",
"oidcServiceDynamicRegistrationExportedVars":"Exported vars for dynamic registration",
"oidcServiceDynamicRegistrationExtraClaims":"Extra claims for dynamic registration",
"oidcServiceIDTokenExpiration":"ID Token expiration",
"oidcServiceOfflineSessionExpiration":"Offline session expiration",
"oidcStorage":"Sessions module name",

View File

@ -615,6 +615,8 @@
"oidcServiceKeyIdSig":"Signing key ID",
"oidcServiceAuthorizationCodeExpiration":"Authorization Code expiration",
"oidcServiceAccessTokenExpiration":"Access Token expiration",
"oidcServiceDynamicRegistrationExportedVars":"Exported vars for dynamic registration",
"oidcServiceDynamicRegistrationExtraClaims":"Extra claims for dynamic registration",
"oidcServiceIDTokenExpiration":"ID Token expiration",
"oidcServiceOfflineSessionExpiration":"Offline session expiration",
"oidcStorage":"Sessions module name",

View File

@ -615,6 +615,8 @@
"oidcServiceKeyIdSig":"Identifiant de clef de signature",
"oidcServiceAuthorizationCodeExpiration":"Expiration des codes d'autorisation",
"oidcServiceAccessTokenExpiration":"Expiration des jetons d'accès",
"oidcServiceDynamicRegistrationExportedVars":"Variables exportées pour l'enregistrement dynamique",
"oidcServiceDynamicRegistrationExtraClaims":"Claims supplémentaires pour l'enregistrement dynamique",
"oidcServiceIDTokenExpiration":"Expiration des jetons d'identité",
"oidcServiceOfflineSessionExpiration":"Expiration des sessions hors-ligne",
"oidcStorage":"Nom du module des sessions",

View File

@ -615,6 +615,8 @@
"oidcServiceKeyIdSig":"ID del codice di accesso",
"oidcServiceAuthorizationCodeExpiration":"Authorization Code expiration",
"oidcServiceAccessTokenExpiration":"Scadenza accesso token",
"oidcServiceDynamicRegistrationExportedVars":"Exported vars for dynamic registration",
"oidcServiceDynamicRegistrationExtraClaims":"Extra claims for dynamic registration",
"oidcServiceIDTokenExpiration":"Scadenza ID Token",
"oidcServiceOfflineSessionExpiration":"Offline session expiration",
"oidcStorage":"Nome del modulo Sessioni",

View File

@ -615,6 +615,8 @@
"oidcServiceKeyIdSig":"Anahtar ID imzalama",
"oidcServiceAuthorizationCodeExpiration":"Yetkilendirme Kodu sona erme",
"oidcServiceAccessTokenExpiration":"Erişim Jetonu sona erme",
"oidcServiceDynamicRegistrationExportedVars":"Exported vars for dynamic registration",
"oidcServiceDynamicRegistrationExtraClaims":"Extra claims for dynamic registration",
"oidcServiceIDTokenExpiration":"ID Jetonu sona erme",
"oidcServiceOfflineSessionExpiration":"Çevrimdışı oturum sona erme",
"oidcStorage":"Oturumlar modülü adı",

View File

@ -615,6 +615,8 @@
"oidcServiceKeyIdSig":"Khóa ID chính",
"oidcServiceAuthorizationCodeExpiration":"Authorization Code expiration",
"oidcServiceAccessTokenExpiration":"Access Token expiration",
"oidcServiceDynamicRegistrationExportedVars":"Exported vars for dynamic registration",
"oidcServiceDynamicRegistrationExtraClaims":"Extra claims for dynamic registration",
"oidcServiceIDTokenExpiration":"ID Token expiration",
"oidcServiceOfflineSessionExpiration":"Offline session expiration",
"oidcStorage":"Tên mô-đun phiên",

View File

@ -615,6 +615,8 @@
"oidcServiceKeyIdSig":"Signing key ID",
"oidcServiceAuthorizationCodeExpiration":"Authorization Code expiration",
"oidcServiceAccessTokenExpiration":"Access Token expiration",
"oidcServiceDynamicRegistrationExportedVars":"Exported vars for dynamic registration",
"oidcServiceDynamicRegistrationExtraClaims":"Extra claims for dynamic registration",
"oidcServiceIDTokenExpiration":"ID Token expiration",
"oidcServiceOfflineSessionExpiration":"Offline session expiration",
"oidcStorage":"Sessions module name",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -526,6 +526,7 @@ t/32-CAS-Macros.t
t/32-OIDC-Macro.t
t/32-OIDC-Offline-Session.t
t/32-OIDC-Refresh-Token.t
t/32-OIDC-Register.t
t/32-OIDC-RP-rule.t
t/32-OIDC-Token-Introspection.t
t/32-OIDC-Token-Security.t

View File

@ -1781,6 +1781,24 @@ sub registration {
->{oidcRPMetaDataOptionsUserInfoSignAlg} = $userinfo_signed_response_alg
if defined $userinfo_signed_response_alg;
# Exported Vars
if (
ref( $self->conf->{oidcServiceDynamicRegistrationExportedVars} ) eq
'HASH' )
{
$conf->{oidcRPMetaDataExportedVars}->{$rp} =
$self->conf->{oidcServiceDynamicRegistrationExportedVars};
}
# Extra claims
if (
ref( $self->conf->{oidcServiceDynamicRegistrationExtraClaims} ) eq
'HASH' )
{
$conf->{oidcRPMetaDataOptionsExtraClaims}->{$rp} =
$self->conf->{oidcServiceDynamicRegistrationExtraClaims};
}
if ( $self->confAcc->saveConf($conf) ) {
# Reload RP list

View File

@ -343,7 +343,10 @@ sub notificationServer {
}
else {
push @$res,
{ "uid" => $json->{uid}, "reference" => $json->{reference} };
{
"uid" => $json->{uid},
"reference" => ( $json->{reference} || $json->{ref} )
};
}
}
}

View File

@ -9,7 +9,7 @@
#
package Lemonldap::NG::Portal::Main::Run;
our $VERSION = '2.0.6';
our $VERSION = '2.0.7';
package Lemonldap::NG::Portal::Main;
@ -164,9 +164,10 @@ sub refresh {
my ( $self, $req ) = @_;
$req->mustRedirect(1);
my %data = %{ $req->userData };
$self->userLogger->notice(
'Refresh request for ' . $data{ $self->conf->{whatToTrace} } );
$req->user( $data{_user} || $data{ $self->conf->{whatToTrace} } );
$req->id( $data{_session_id} );
$self->userLogger->notice( 'Refresh request for ' . $req->user );
foreach ( keys %data ) {
delete $data{$_} unless ( /^_/ or /^(?:startTime)$/ );
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1,2 @@
(function(){var r,e,n,t,o;n=function(e,r){return $("#msg").html(window.translate(e)),$("#color").removeClass("message-positive message-warning message-danger alert-success alert-warning alert-danger"),$("#color").addClass("message-"+r),"positive"===r&&(r="success"),$("#color").addClass("alert-"+r)},r=function(e,r,t){var o;if(console.log("Error",t),(o=JSON.parse(e.responseText))&&o.error)return o=o.error.replace(/.* /,""),console.log("Returned error",o),n(o,"warning")},t="",e=function(e){return n("yourTotpKey","warning"),$.ajax({type:"POST",url:portal+"/2fregisters/totp/getkey",dataType:"json",data:{newkey:e},error:r,success:function(e){var r;return e.error?(e.error.match(/totpExistingKey/)&&$("#divToHide").hide(),n(e.error,"warning")):e.portal&&e.user&&e.secret?($("#divToHide").show(),r="otpauth://totp/"+escape(e.portal)+":"+escape(e.user)+"?secret="+e.secret+"&issuer="+escape(e.portal),6!==e.digits&&(r+="&digits="+e.digits),30!==e.interval&&(r+="&period="+e.interval),new QRious({element:document.getElementById("qr"),value:r,size:150}),$("#serialized").text(r),e.newkey?n("yourNewTotpKey","warning"):n("yourTotpKey","success"),t=e.token):n("PE24","danger")}})},o=function(){var e;return(e=$("#code").val())?$.ajax({type:"POST",url:portal+"/2fregisters/totp/verify",dataType:"json",data:{token:t,code:e,TOTPName:$("#TOTPName").val()},error:r,success:function(e){return e.error?e.error.match(/bad(Code|Name)/)?n(e.error,"warning"):n(e.error,"danger"):n("yourKeyIsRegistered","success")}}):n("fillTheForm","warning")},$(document).ready(function(){return e(0),$("#changekey").on("click",function(){return e(1)}),$("#verify").on("click",function(){return o()})})}).call(this);
(function(){var e,r,t,o,n;t=function(e,r){return $("#msg").html(window.translate(e)),$("#color").removeClass("message-positive message-warning message-danger alert-success alert-warning alert-danger"),$("#color").addClass("message-"+r),"positive"===r&&(r="success"),$("#color").addClass("alert-"+r)},e=function(e,r,o){var n;if(console.log("Error",o),(n=JSON.parse(e.responseText))&&n.error)return n=n.error.replace(/.* /,""),console.log("Returned error",n),t(n,"warning")},o="",r=function(r){return t("yourTotpKey","warning"),$.ajax({type:"POST",url:portal+"/2fregisters/totp/getkey",dataType:"json",data:{newkey:r},error:e,success:function(e){var r;return e.error?(e.error.match(/totpExistingKey/)&&$("#divToHide").hide(),t(e.error,"warning")):e.portal&&e.user&&e.secret?($("#divToHide").show(),r="otpauth://totp/"+escape(e.portal)+":"+escape(e.user)+"?secret="+e.secret+"&issuer="+escape(e.portal),6!==e.digits&&(r+="&digits="+e.digits),30!==e.interval&&(r+="&period="+e.interval),new QRious({element:document.getElementById("qr"),value:r,size:150}),$("#serialized").text(r),e.newkey?t("yourNewTotpKey","warning"):t("yourTotpKey","success"),o=e.token):t("PE24","danger")}})},n=function(){var r;return r=$("#code").val(),r?$.ajax({type:"POST",url:portal+"/2fregisters/totp/verify",dataType:"json",data:{token:o,code:r,TOTPName:$("#TOTPName").val()},error:e,success:function(e){return e.error?e.error.match(/bad(Code|Name)/)?t(e.error,"warning"):t(e.error,"danger"):t("yourKeyIsRegistered","success")}}):t("fillTheForm","warning")},$(document).ready(function(){return r(0),$("#changekey").on("click",function(){return r(1)}),$("#verify").on("click",function(){return n()})})}).call(this);
//# sourceMappingURL=lemonldap-ng-portal/site/htdocs/static/common/js/totpregistration.min.js.map

View File

@ -1 +1 @@
{"version":3,"sources":["lemonldap-ng-portal/site/htdocs/static/common/js/totpregistration.js"],"names":["displayError","getKey","setMsg","token","verify","msg","level","$","html","window","translate","removeClass","addClass","j","status","err","res","console","log","JSON","parse","responseText","error","replace","reset","ajax","type","url","portal","dataType","data","newkey","success","s","match","hide","user","secret","show","escape","digits","interval","QRious","element","document","getElementById","value","size","text","val","code","TOTPName","ready","on","call","this"],"mappings":"CAMA,WACE,IAAIA,EAAcC,EAAQC,EAAQC,EAAOC,EAEzCF,EAAS,SAASG,EAAKC,GAOrB,OANAC,EAAE,QAAQC,KAAKC,OAAOC,UAAUL,IAChCE,EAAE,UAAUI,YAAY,4FACxBJ,EAAE,UAAUK,SAAS,WAAaN,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUK,SAAS,SAAWN,IAGzCN,EAAe,SAASa,EAAGC,EAAQC,GACjC,IAAIC,EAGJ,GAFAC,QAAQC,IAAI,QAASH,IACrBC,EAAMG,KAAKC,MAAMP,EAAEQ,gBACRL,EAAIM,MAGb,OAFAN,EAAMA,EAAIM,MAAMC,QAAQ,MAAO,IAC/BN,QAAQC,IAAI,iBAAkBF,GACvBd,EAAOc,EAAK,YAIvBb,EAAQ,GAERF,EAAS,SAASuB,GAEhB,OADAtB,EAAO,cAAe,WACfK,EAAEkB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVC,KAAM,CACJC,OAAQP,GAEVF,MAAOtB,EACPgC,QAAS,SAASF,GAChB,IAAQG,EACR,OAAIH,EAAKR,OACHQ,EAAKR,MAAMY,MAAM,oBACnB3B,EAAE,cAAc4B,OAEXjC,EAAO4B,EAAKR,MAAO,YAEtBQ,EAAKF,QAAUE,EAAKM,MAAQN,EAAKO,QAGvC9B,EAAE,cAAc+B,OAChBL,EAAI,kBAAqBM,OAAOT,EAAKF,QAAW,IAAOW,OAAOT,EAAKM,MAAS,WAAaN,EAAKO,OAAS,WAAcE,OAAOT,EAAKF,QAC7G,IAAhBE,EAAKU,SACPP,GAAK,WAAaH,EAAKU,QAEH,KAAlBV,EAAKW,WACPR,GAAK,WAAaH,EAAKW,UAEpB,IAAIC,OAAO,CACdC,QAASC,SAASC,eAAe,MACjCC,MAAOb,EACPc,KAAM,MAERxC,EAAE,eAAeyC,KAAKf,GAClBH,EAAKC,OACP7B,EAAO,iBAAkB,WAEzBA,EAAO,cAAe,WAEjBC,EAAQ2B,EAAK3B,OArBXD,EAAO,OAAQ,cA0B9BE,EAAS,WACP,IAAI6C,EAEJ,OADAA,EAAM1C,EAAE,SAAS0C,OAIR1C,EAAEkB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVC,KAAM,CACJ3B,MAAOA,EACP+C,KAAMD,EACNE,SAAU5C,EAAE,aAAa0C,OAE3B3B,MAAOtB,EACPgC,QAAS,SAASF,GAChB,OAAIA,EAAKR,MACHQ,EAAKR,MAAMY,MAAM,kBACZhC,EAAO4B,EAAKR,MAAO,WAEnBpB,EAAO4B,EAAKR,MAAO,UAGrBpB,EAAO,sBAAuB,cApBpCA,EAAO,cAAe,YA2BjCK,EAAEqC,UAAUQ,MAAM,WAKhB,OAJAnD,EAAO,GACPM,EAAE,cAAc8C,GAAG,QAAS,WAC1B,OAAOpD,EAAO,KAETM,EAAE,WAAW8C,GAAG,QAAS,WAC9B,OAAOjD,UAIVkD,KAAKC"}
{"version":3,"sources":["lemonldap-ng-portal/site/htdocs/static/common/js/totpregistration.js"],"names":["displayError","getKey","setMsg","token","verify","msg","level","$","html","window","translate","removeClass","addClass","j","status","err","res","console","log","JSON","parse","responseText","error","replace","reset","ajax","type","url","portal","dataType","data","newkey","success","s","match","hide","user","secret","show","escape","digits","interval","QRious","element","document","getElementById","value","size","text","val","code","TOTPName","ready","on","call","this"],"mappings":"CAMA,WACE,GAAIA,GAAcC,EAAQC,EAAQC,EAAOC,CAEzCF,GAAS,SAASG,EAAKC,GAOrB,MANAC,GAAE,QAAQC,KAAKC,OAAOC,UAAUL,IAChCE,EAAE,UAAUI,YAAY,4FACxBJ,EAAE,UAAUK,SAAS,WAAaN,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUK,SAAS,SAAWN,IAGzCN,EAAe,SAASa,EAAGC,EAAQC,GACjC,GAAIC,EAGJ,IAFAC,QAAQC,IAAI,QAASH,IACrBC,EAAMG,KAAKC,MAAMP,EAAEQ,gBACRL,EAAIM,MAGb,MAFAN,GAAMA,EAAIM,MAAMC,QAAQ,MAAO,IAC/BN,QAAQC,IAAI,iBAAkBF,GACvBd,EAAOc,EAAK,YAIvBb,EAAQ,GAERF,EAAS,SAASuB,GAEhB,MADAtB,GAAO,cAAe,WACfK,EAAEkB,MACPC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVC,MACEC,OAAQP,GAEVF,MAAOtB,EACPgC,QAAS,SAASF,GAChB,GAAQG,EACR,OAAIH,GAAKR,OACHQ,EAAKR,MAAMY,MAAM,oBACnB3B,EAAE,cAAc4B,OAEXjC,EAAO4B,EAAKR,MAAO,YAEtBQ,EAAKF,QAAUE,EAAKM,MAAQN,EAAKO,QAGvC9B,EAAE,cAAc+B,OAChBL,EAAI,kBAAqBM,OAAOT,EAAKF,QAAW,IAAOW,OAAOT,EAAKM,MAAS,WAAaN,EAAKO,OAAS,WAAcE,OAAOT,EAAKF,QAC7G,IAAhBE,EAAKU,SACPP,GAAK,WAAaH,EAAKU,QAEH,KAAlBV,EAAKW,WACPR,GAAK,WAAaH,EAAKW,UAEpB,GAAIC,SACPC,QAASC,SAASC,eAAe,MACjCC,MAAOb,EACPc,KAAM,MAERxC,EAAE,eAAeyC,KAAKf,GAClBH,EAAKC,OACP7B,EAAO,iBAAkB,WAEzBA,EAAO,cAAe,WAEjBC,EAAQ2B,EAAK3B,OArBXD,EAAO,OAAQ,cA0B9BE,EAAS,WACP,GAAI6C,EAEJ,OADAA,GAAM1C,EAAE,SAAS0C,MACZA,EAGI1C,EAAEkB,MACPC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVC,MACE3B,MAAOA,EACP+C,KAAMD,EACNE,SAAU5C,EAAE,aAAa0C,OAE3B3B,MAAOtB,EACPgC,QAAS,SAASF,GAChB,MAAIA,GAAKR,MACHQ,EAAKR,MAAMY,MAAM,kBACZhC,EAAO4B,EAAKR,MAAO,WAEnBpB,EAAO4B,EAAKR,MAAO,UAGrBpB,EAAO,sBAAuB,cApBpCA,EAAO,cAAe,YA2BjCK,EAAEqC,UAAUQ,MAAM,WAKhB,MAJAnD,GAAO,GACPM,EAAE,cAAc8C,GAAG,QAAS,WAC1B,MAAOpD,GAAO,KAETM,EAAE,WAAW8C,GAAG,QAAS,WAC9B,MAAOjD,WAIVkD,KAAKC","file":"lemonldap-ng-portal/site/htdocs/static/common/js/totpregistration.min.js"}

View File

@ -114,10 +114,10 @@ m%<form id="lformKerberos" action="#" method="post" class="login Kerberos">%,
' Action # found'
) or explain( $res->[2]->[0], '<form id="lformSSL"' );
my $header = getHeader( $res, 'Content-Security-Policy' );
ok( $header =~ m%;form-action \'self\' https://test.example.com;%,
ok( $header =~ m%;form-action \* https://test.example.com;%,
' CSP URL found' )
or
explain( $res->[1], 'form-action \'self\' https://test.example.com;' );
explain( $res->[1], 'form-action * https://test.example.com;' );
ok( $res->[2]->[0] !~ /4_demo/, '4_Demo not displayed' );
ok(
$res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,

View File

@ -0,0 +1,178 @@
use lib 'inc';
use Test::More;
use strict;
use IO::String;
use LWP::UserAgent;
use LWP::Protocol::PSGI;
use MIME::Base64;
use JSON;
BEGIN {
require 't/test-lib.pm';
}
my $debug = 'error';
my $res;
# Initialization
ok( my $op = op(), 'OP portal' );
my $register_data = {
"application_type" => "web",
"redirect_uris" => [
"https://client.example.org/callback",
"https://client.example.org/callback2"
],
"client_name" => "My Example",
"logo_uri" => "https://client.example.org/logo.png",
"subject_type" => "pairwise",
"token_endpoint_auth_method" => "client_secret_basic",
};
my $register_data_json = JSON::to_json($register_data);
ok(
$res = $op->_post(
"/oauth2/register",
IO::String->new($register_data_json),
accept => 'application/json',
length => length($register_data_json),
),
"Post register data"
);
ok( $res->[0] == 201, "Return code is 201" );
my $register_answer = JSON::from_json( $res->[2]->[0] );
ok( defined $register_answer->{client_id},
"Client ID found in answer: " . $register_answer->{client_id} );
# New configuration registered
my $confFile = "t/lmConf-2.json";
my $conf = JSON::from_json(`cat $confFile`);
# Check saved data
my $rpId = ( keys %{ $conf->{oidcRPMetaDataOptions} } )[0];
ok(
$conf->{oidcRPMetaDataOptions}->{$rpId}->{oidcRPMetaDataOptionsClientID} eq
$register_answer->{client_id},
"Client ID saved in configuration"
);
# Check extra claims and extra attributes
ok(
$conf->{oidcRPMetaDataOptionsExtraClaims}->{$rpId}->{"extra_claim"} eq
"extra_var",
"Extra claim defined"
);
ok( $conf->{oidcRPMetaDataExportedVars}->{$rpId}->{"extra_var"} eq "mail",
"Extra variable defined" );
unlink $confFile;
clean_sessions();
done_testing();
sub op {
return LLNG::Manager::Test->new(
{
ini => {
logLevel => $debug,
domain => 'idp.com',
portal => 'http://auth.op.com',
authentication => 'Demo',
userDB => 'Same',
issuerDBOpenIDConnectActivation => 1,
issuerDBOpenIDConnectRule => '$uid eq "french"',
oidcRPMetaDataExportedVars => {
rp => {
email => "mail",
family_name => "extract_sn",
name => "cn"
}
},
oidcServiceDynamicRegistrationExportedVars =>
{ "extra_var" => "mail" },
oidcServiceDynamicRegistrationExtraClaims =>
{ "extra_claim" => "extra_var" },
oidcServiceMetaDataAuthorizeURI => "authorize",
oidcServiceMetaDataCheckSessionURI => "checksession.html",
oidcServiceMetaDataJWKSURI => "jwks",
oidcServiceMetaDataEndSessionURI => "logout",
oidcServiceMetaDataRegistrationURI => "register",
oidcServiceMetaDataTokenURI => "token",
oidcServiceMetaDataUserInfoURI => "userinfo",
oidcServiceAllowHybridFlow => 1,
oidcServiceAllowImplicitFlow => 1,
oidcServiceAllowDynamicRegistration => 1,
oidcServiceAllowAuthorizationCodeFlow => 1,
oidcRPMetaDataMacros => {
rp => {
extract_sn => '(split(/\s/, $cn))[1]',
}
},
oidcRPMetaDataOptions => {
rp => {
oidcRPMetaDataOptionsDisplayName => "RP",
oidcRPMetaDataOptionsIDTokenExpiration => 3600,
oidcRPMetaDataOptionsClientID => "rpid",
oidcRPMetaDataOptionsIDTokenSignAlg => "HS512",
oidcRPMetaDataOptionsBypassConsent => 1,
oidcRPMetaDataOptionsClientSecret => "rpsecret",
oidcRPMetaDataOptionsUserIDAttr => "",
oidcRPMetaDataOptionsAccessTokenExpiration => 3600,
}
},
oidcOPMetaDataOptions => {},
oidcOPMetaDataJSON => {},
oidcOPMetaDataJWKS => {},
oidcServiceMetaDataAuthnContext => {
'loa-4' => 4,
'loa-1' => 1,
'loa-5' => 5,
'loa-2' => 2,
'loa-3' => 3
},
oidcServicePrivateKeySig => "-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAs2jsmIoFuWzMkilJaA8//5/T30cnuzX9GImXUrFR2k9EKTMt
GMHCdKlWOl3BV+BTAU9TLz7Jzd/iJ5GJ6B8TrH1PHFmHpy8/qE/S5OhinIpIi7eb
ABqnoVcwDdCa8ugzq8k8SWxhRNXfVIlwz4NH1caJ8lmiERFj7IvNKqEhzAk0pyDr
8hubveTC39xREujKlsqutpPAFPJ3f2ybVsdykX5rx0h5SslG3jVWYhZ/SOb2aIzO
r0RMjhQmsYRwbpt3anjlBZ98aOzg7GAkbO8093X5VVk9vaPRg0zxJQ0Do0YLyzkR
isSAIFb0tdKuDnjRGK6y/N2j6At2HjkxntbtGQIDAQABAoIBADYq6LxJd977LWy3
0HT9nboFPIf+SM2qSEc/S5Po+6ipJBA4ZlZCMf7dHa6znet1TDpqA9iQ4YcqIHMH
6xZNQ7hhgSAzG9TrXBHqP+djDlrrGWotvjuy0IfS9ixFnnLWjrtAH9afRWLuG+a/
NHNC1M6DiiTE0TzL/lpt/zzut3CNmWzH+t19X6UsxUg95AzooEeewEYkv25eumWD
mfQZfCtSlIw1sp/QwxeJa/6LJw7KcPZ1wXUm1BN0b9eiKt9Cmni1MS7elgpZlgGt
xtfGTZtNLQ7bgDiM8MHzUfPBhbceNSIx2BeCuOCs/7eaqgpyYHBbAbuBQex2H61l
Lcc3Tz0CgYEA4Kx/avpCPxnvsJ+nHVQm5d/WERuDxk4vH1DNuCYBvXTdVCGADf6a
F5No1JcTH3nPTyPWazOyGdT9LcsEJicLyD8vCM6hBFstG4XjqcAuqG/9DRsElpHQ
yi1zc5DNP7Vxmiz9wII0Mjy0abYKtxnXh9YK4a9g6wrcTpvShhIcIb8CgYEAzGzG
lorVCfX9jXULIznnR/uuP5aSnTEsn0xJeqTlbW0RFWLdj8aIL1peirh1X89HroB9
GeTNqEJXD+3CVL2cx+BRggMDUmEz4hR59meZCDGUyT5fex4LIsceb/ESUl2jo6Sw
HXwWbN67rQ55N4oiOcOppsGxzOHkl5HdExKidycCgYEAr5Qev2tz+fw65LzfzHvH
Kj4S/KuT/5V6He731cFd+sEpdmX3vPgLVAFPG1Q1DZQT/rTzDDQKK0XX1cGiLG63
NnaqOye/jbfzOF8Z277kt51NFMDYhRLPKDD82IOA4xjY/rPKWndmcxwdob8yAIWh
efY76sMz6ntCT+xWSZA9i+ECgYBWMZM2TIlxLsBfEbfFfZewOUWKWEGvd9l5vV/K
D5cRIYivfMUw5yPq2267jPUolayCvniBH4E7beVpuPVUZ7KgcEvNxtlytbt7muil
5Z6X3tf+VodJ0Swe2NhTmNEB26uwxzLe68BE3VFCsbSYn2y48HAq+MawPZr18bHG
ZfgMxwKBgHHRg6HYqF5Pegzk1746uH2G+OoCovk5ylGGYzcH2ghWTK4agCHfBcDt
EYqYAev/l82wi+OZ5O8U+qjFUpT1CVeUJdDs0o5u19v0UJjunU1cwh9jsxBZAWLy
PAGd6SWf4S3uQCTw6dLeMna25YIlPh5qPA6I/pAahe8e3nSu2ckl
-----END RSA PRIVATE KEY-----
",
oidcServicePublicKeySig => "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs2jsmIoFuWzMkilJaA8/
/5/T30cnuzX9GImXUrFR2k9EKTMtGMHCdKlWOl3BV+BTAU9TLz7Jzd/iJ5GJ6B8T
rH1PHFmHpy8/qE/S5OhinIpIi7ebABqnoVcwDdCa8ugzq8k8SWxhRNXfVIlwz4NH
1caJ8lmiERFj7IvNKqEhzAk0pyDr8hubveTC39xREujKlsqutpPAFPJ3f2ybVsdy
kX5rx0h5SslG3jVWYhZ/SOb2aIzOr0RMjhQmsYRwbpt3anjlBZ98aOzg7GAkbO80
93X5VVk9vaPRg0zxJQ0Do0YLyzkRisSAIFb0tdKuDnjRGK6y/N2j6At2Hjkxntbt
GQIDAQAB
-----END PUBLIC KEY-----
",
}
}
);
}

View File

@ -1,6 +1,7 @@
use Test::More;
use strict;
use IO::String;
use JSON qw(from_json);
BEGIN {
require 't/test-lib.pm';
@ -132,6 +133,36 @@ ok( $res->[2]->[0] =~ /"uid":"everyone"/, 'Wildcard found' )
or print STDERR Dumper( $res->[2]->[0] );
count(4);
ok(
$res = $client->_get(
'/notifications/bad_uid', type => 'application/json',
),
'List notifications for bad uid'
);
ok(
$res->[2]->[0] =~ /"reference":"testrefall"/,
'Notification for all users found'
) or print STDERR Dumper( $res->[2]->[0] );
count(2);
ok(
$res = $client->_get(
'/notifications/_allPending_', type => 'application/json',
),
'List all pending notifications'
);
ok( $json = eval { from_json( $res->[2]->[0] ) }, 'Response is JSON' );
ok( scalar @{ $json->{result} } == 3, 'Three notifications found' )
or print STDERR Dumper($json);
foreach ( @{$json->{result}} ) {
ok( $_->{reference} =~ /^testref/, "Reference \'$_->{reference}\' found" )
or print STDERR Dumper($json);
ok( $_->{uid} =~ /^(dwho|everyone)$/, "UID \'$_->{uid}\' found" )
or print STDERR Dumper($json);
}
count(9);
ok(
$res = $client->_get(
'/notifications/dwho', type => 'application/json',
@ -271,6 +302,17 @@ ok( $res->[2]->[0] =~ /"result"\s*:\s*4/, 'Notifications have been inserted' )
or print STDERR Dumper( $res->[2]->[0] );
count(2);
ok(
$res = $client->_get(
'/notifications/_allExisting_', type => 'application/json',
),
'List all existing notifications'
);
ok( $json = eval { from_json( $res->[2]->[0] ) }, 'Response is JSON' );
ok( scalar @{ $json->{result} } == 5, 'Five notifications found' )
or print STDERR Dumper($json);
count(3);
# Try to authenticate with "dwho"
# -------------------------------
ok(
@ -321,6 +363,7 @@ ok(
"Accept notification"
);
expectOK($res);
$id = expectCookie($res);
$client->logout($id);
# Try to authenticate with "rtyler"
@ -369,7 +412,19 @@ ok(
"Accept notification"
);
expectOK($res);
$id = expectCookie($res);
$client->logout($id);
ok(
$res = $client->_get(
'/notifications/_allPending_', type => 'application/json',
),
'List all pending notifications'
);
ok( $json = eval { from_json( $res->[2]->[0] ) }, 'Response is JSON' );
ok( scalar @{ $json->{result} } == 3, 'Three notifications found' )
or print STDERR Dumper($json);
count(3);
clean_sessions();
done_testing( count() );

View File

@ -141,7 +141,8 @@ sub count_sessions {
sub getCache {
require Cache::FileCache;
return Cache::FileCache->new( {
return Cache::FileCache->new(
{
namespace => 'lemonldap-ng-session',
cache_root => $tmpDir,
cache_depth => 0,
@ -416,7 +417,8 @@ sub exceptCspFormOK {
}
if ( $csp =~ /\s\*(?:\s.*)?\s*$/
or ( $host eq '#' and $csp =~ /'self'/ )
or $csp =~ m#\bhttps?://$host\b# )
or $csp =~ m#\bhttps?://$host\b#
or $csp =~ m#\*# )
{
pass(" CSP header authorize POST request to $host");
}
@ -598,7 +600,7 @@ has ini => (
main::ok( $self->{p} = $self->class->new(), 'Portal object' );
main::count(1);
unless ( $self->confFailure ) {
main::ok( $self->{p}->init($ini), 'Init' );
main::ok( $self->{p}->init($ini), 'Init' );
main::ok( $self->{app} = $self->{p}->run(), 'Portal app' );
main::count(2);
no warnings 'redefine';
@ -703,7 +705,8 @@ to test content I<(to launch a C<expectForm()> for example)>.
sub _get {
my ( $self, $path, %args ) = @_;
my $res = $self->app->( {
my $res = $self->app->(
{
'HTTP_ACCEPT' => $args{accept}
|| 'application/json, text/plain, */*',
'HTTP_ACCEPT_LANGUAGE' => 'fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3',
@ -755,7 +758,8 @@ sub _post {
my ( $self, $path, $body, %args ) = @_;
die "$body must be a IO::Handle"
unless ( ref($body) and $body->can('read') );
my $res = $self->app->( {
my $res = $self->app->(
{
'HTTP_ACCEPT' => $args{accept}
|| 'application/json, text/plain, */*',
'HTTP_ACCEPT_LANGUAGE' => 'fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3',

View File

@ -1,11 +1,3 @@
#==============================================================================
# Specification file for LemonLDAP::NG
#
# Install LemonLDAP::NG modules, htdocs and scripts
# Authority: dries
# Upstream: Xavier Guimard <x,guimard$free,fr>
#==============================================================================
#==============================================================================
# Variables
#==============================================================================
@ -19,27 +11,14 @@
%global lm_sbindir %{_libexecdir}/%{name}/sbin
# Apache configuration directory
%if 0%{?rhel}%{?fedora}
%global apache_confdir %{_sysconfdir}/httpd/conf.d
%else
%global apache_confdir %{_sysconfdir}/apache2/conf.d
%endif
# Apache User and Group
%if 0%{?rhel}%{?fedora}
%global lm_apacheuser apache
%global lm_apachegroup apache
%else
%global lm_apacheuser wwwrun
%global lm_apachegroup www
%endif
# Apache version
%if 0%{?fedora} || 0%{?rhel} >= 7
%global apache_version 2.4
%else
%global apache_version 2
%endif
%global lm_dnsdomain example.com
@ -49,8 +28,8 @@
# Main package
#==============================================================================
Name: lemonldap-ng
Version: 2.0.6
Release: %{?pre_release:0.}1%{?pre_release:.%{pre_release}}%{?dist}
Version: 2.0.7
Release: %{?pre_release:0.}2%{?pre_release:.%{pre_release}}%{?dist}
Summary: LemonLDAP-NG WebSSO
License: GPLv2+
URL: http://lemonldap-ng.org
@ -71,6 +50,7 @@ BuildRequires: perl(Apache2::RequestUtil)
BuildRequires: perl(Apache2::ServerRec)
BuildRequires: perl(Apache2::ServerUtil)
BuildRequires: perl(Apache::Session)
BuildRequires: perl(Apache::Session::Browseable)
BuildRequires: perl(Apache::Session::Generate::MD5)
BuildRequires: perl(APR::Table)
BuildRequires: perl(AuthCAS)
@ -95,6 +75,7 @@ BuildRequires: perl(Crypt::OpenSSL::RSA)
BuildRequires: perl(Crypt::OpenSSL::X509)
BuildRequires: perl(Crypt::Rijndael)
BuildRequires: perl(Crypt::URandom)
BuildRequires: perl(Cwd)
BuildRequires: perl(Data::Dumper)
BuildRequires: perl(DBI)
BuildRequires: perl(Digest::HMAC_SHA1)
@ -120,11 +101,16 @@ BuildRequires: perl(Getopt::Std)
BuildRequires: perl(GSSAPI)
BuildRequires: perl(HTML::Template)
BuildRequires: perl(HTTP::Headers)
BuildRequires: perl(HTTP::Message)
BuildRequires: perl(HTTP::Request)
BuildRequires: perl(Image::Magick)
BuildRequires: perl(IO::Pipe)
BuildRequires: perl(IO::Select)
BuildRequires: perl(IO::Socket::INET)
BuildRequires: perl(IO::String)
BuildRequires: perl(IPC::Run)
BuildRequires: perl(JSON)
BuildRequires: perl(JSON::XS)
%if 0%{?fedora}
BuildRequires: perl(Lasso)
BuildRequires: perl(Glib)
@ -136,9 +122,13 @@ BuildRequires: perl(MIME::Base64)
BuildRequires: perl(MIME::Entity)
BuildRequires: perl(mod_perl2)
BuildRequires: perl(Mouse)
# Not packaged
# BuildRequires: perl(Net::Facebook::Oauth2)
BuildRequires: perl(Net::LDAP)
BuildRequires: perl(Net::LDAP::Extension::SetPassword)
BuildRequires: perl(Net::LDAP::Util)
BuildRequires: perl(Net::OAuth)
BuildRequires: perl(Net::OpenID::Consumer)
BuildRequires: perl(Net::OpenID::Server)
BuildRequires: perl(Plack)
BuildRequires: perl(Plack::Handler::CGI)
@ -154,7 +144,7 @@ BuildRequires: perl(Regexp::Assemble)
BuildRequires: perl(Regexp::Common)
BuildRequires: perl(Safe)
BuildRequires: perl(Scalar::Util)
%if 0%{?fedora}
%if 0%{?fedora}%{?el8}
BuildRequires: perl(Sentry::Raven)
%endif
BuildRequires: perl(SOAP::Lite)
@ -164,6 +154,7 @@ BuildRequires: perl(String::Random)
BuildRequires: perl(Sys::Syslog)
BuildRequires: perl(Test::MockObject)
BuildRequires: perl(Test::Pod) >= 1.00
BuildRequires: perl(Text::Unidecode)
BuildRequires: perl(Time::Local)
BuildRequires: perl(Unicode::String)
BuildRequires: perl(URI)
@ -171,7 +162,7 @@ BuildRequires: perl(URI::Escape)
BuildRequires: perl(URI::URL)
BuildRequires: perl(utf8)
BuildRequires: perl(warnings)
%if 0%{?fedora}
%if 0%{?fedora}%{?el8}
BuildRequires: perl(Web::ID)
%endif
BuildRequires: perl(XML::LibXML)
@ -188,14 +179,10 @@ Requires: lemonldap-ng-portal = %{version}-%{release}
Requires: lemonldap-ng-test = %{version}-%{release}
# Setup requires filtering
%if 0%{?rhel} >= 7
%{?perl_default_filter}
%global __requires_exclude perl\\(Lasso|perl\\(Web::ID|perl\\(Sentry::Raven
%endif
%{?el7:%global __requires_exclude perl\\(Lasso|perl\\(Web::ID|perl\\(Sentry::Raven}
%{?el8:%global __requires_exclude perl\\(Lasso}
%if 0%{?fedora}
%{?perl_default_filter}
%endif
%description
LemonLdap::NG is a modular Web-SSO based on Apache::Session modules. It
@ -210,16 +197,12 @@ So you can have a full AAA protection for your web space as described below.
%package conf
Summary: LemonLDAP-NG configuration
Requires: perl(Apache::Session)
Requires: perl(Apache::Session::Browseable)
Requires: perl(IO::String)
Requires: perl(Lemonldap::NG::Common) = %{version}-%{release}
Requires: perl(mod_perl2)
%if 0%{?rhel}%{?fedora}
Requires(post): httpd
Requires: mod_fcgid
%else
Requires(post): apache2
Requires: apache2-mod_fcgid
%endif
%description conf
This package contains the main storage configuration.
@ -239,9 +222,7 @@ This package contains HTML documentation.
#==============================================================================
%package handler
Summary: LemonLDAP-NG handler
%if 0%{?rhel}%{?fedora}
Requires: crontabs
%endif
Requires: lemonldap-ng-conf = %{version}-%{release}
Requires: perl(Lemonldap::NG::Handler) = %{version}-%{release}
@ -264,11 +245,13 @@ This package deploys the administration interface and sessions explorer.
#==============================================================================
%package portal
Summary: LemonLDAP-NG authentication portal
%if 0%{?rhel}%{?fedora}
Requires: crontabs
%endif
Requires: lemonldap-ng-conf = %{version}-%{release}
Requires: perl(Lemonldap::NG::Portal) = %{version}-%{release}
# Not packaged
#Requires: perl(Net::Facebook::Oauth2)
Requires: perl(Net::OAuth)
Requires: perl(Net::OpenID::Consumer)
%description portal
This package deploys the authentication portal.
@ -289,11 +272,7 @@ This package deploys small test applications.
%package fastcgi-server
Summary: LemonLDAP-NG FastCGI Server
Requires: lemonldap-ng-conf = %{version}-%{release}
%if 0%{?rhel}%{?fedora}
Requires: mod_fcgid
%else
Requires: apache2-mod_fcgid
%endif
Requires: perl(FCGI::ProcManager)
%description fastcgi-server
@ -372,16 +351,16 @@ This package installs the authentication portal.
# Building
#==============================================================================
%build
%{__make} %{?_smp_mflags} configure \
make %{?_smp_mflags} configure \
STORAGECONFFILE=%{lm_storagefile} \
PERLOPTIONS="INSTALLDIRS=vendor"
%{__make} %{?_smp_mflags}
make %{?_smp_mflags}
#==============================================================================
# Installation
#============================================================================
%install
%{__make} %{?_smp_mflags} install \
make %{?_smp_mflags} install \
DESTDIR=%{buildroot} \
PREFIX=%{lm_prefix} \
BINDIR=%{lm_bindir} \
@ -503,7 +482,7 @@ chmod 644 %{buildroot}/usr/share/lemonldap-ng/test/cas.php
%check
sed -i 's:^dirName.*:dirName = %{buildroot}%{lm_vardir}/conf:' \
%{buildroot}%{lm_storagefile}
%{__make} %{?_smp_mflags} test \
make %{?_smp_mflags} test \
LLNG_DEFAULTCONFFILE=%{buildroot}%{lm_storagefile}
sed -i 's:^dirName.*:dirName = %{lm_vardir}/conf:' \
%{buildroot}%{lm_storagefile}
@ -562,12 +541,16 @@ fi
%config(noreplace) %{apache_confdir}/z-lemonldap-ng-manager.conf
%config(noreplace) %{apache_confdir}/z-lemonldap-ng-portal.conf
%{_mandir}/man1/convertConfig*
%if "%{version}" >= "2.0.7"
%{_mandir}/man1/convertSessions*
%endif
%dir %{_libexecdir}/%{name}
%dir %{lm_sbindir}
%dir %{lm_bindir}
%{lm_bindir}/convertConfig
%if "%{version}" >= "2.0.7"
%{lm_bindir}/convertSessions
%endif
%{lm_bindir}/importMetadata
%{lm_bindir}/lmMigrateConfFiles2ini
%{lm_bindir}/rotateOidcKeys
@ -666,6 +649,11 @@ fi
# Changelog
#==============================================================================
%changelog
* Fri Dec 06 2019 Xavier Bachelot <xavier@bachelot.org> - 2.0.6-2
- Tweak for EL8.
- Enhance BuildRequires and Requires.
- Spec clean up.
* Tue Sep 24 2019 Clement Oudot <clem.oudot@gmail.com> - 2.0.6-1
- Update to 2.0.6
@ -678,9 +666,6 @@ fi
* Sun May 12 2019 Clement Oudot <clem.oudot@gmail.com> - 2.0.4-1
- Update to 2.0.4
* Sun May 12 2019 Clement Oudot <clem.oudot@gmail.com> - 1.9.19-1
- Update to 1.9.19
* Thu Apr 11 2019 Clement Oudot <clem.oudot@gmail.com> - 2.0.3-1
- Update to 2.0.3
@ -699,39 +684,15 @@ fi
* Fri Nov 30 2018 Clement Oudot <clem.oudot@gmail.com> - 2.0.0-1
- Update to 2.0.0
* Fri Oct 05 2018 Clement Oudot <clem.oudot@gmail.com> - 1.9.18-1
- Update to 1.9.18
* Fri Jul 20 2018 Clement Oudot <clem.oudot@gmail.com> - 2.0.0~beta1-1
- First beta version for 2.0.0
* Sun Jun 17 2018 Clement Oudot <clem.oudot@gmail.com> - 1.9.17-1
- Update to 1.9.17
* Fri Mar 16 2018 Clement Oudot <clem.oudot@gmail.com> - 1.9.16-1
- Update to 1.9.16
* Fri Jan 26 2018 Clement Oudot <clem.oudot@gmail.com> - 2.0.0~alpha3-1
- Third alpha version for 2.0.0
* Tue Jan 23 2018 Clement Oudot <clem.oudot@gmail.com> - 1.9.15-1
- Update to 1.9.15
* Fri Nov 24 2017 Clement Oudot <clem.oudot@gmail.com> - 1.9.14-1
- Update to 1.9.14
* Fri Sep 29 2017 Clement Oudot <clem.oudot@gmail.com> - 1.9.13-1
- Update to 1.9.13
* Thu Sep 14 2017 Clement Oudot <clem.oudot@gmail.com> - 2.0.0~alpha2-1
- Second alpha version for 2.0.0
* Tue Sep 12 2017 Clement Oudot <clem.oudot@gmail.com> - 1.9.12-1
- Update to 1.9.12
* Fri Sep 01 2017 Clement Oudot <clem.oudot@gmail.com> - 1.9.11-1
- Update to 1.9.11
* Mon Jul 10 2017 Clement Oudot <clem.oudot@gmail.com> - 2.0.0~alpha1-1
- First alpha version for 2.0.0
@ -750,36 +711,21 @@ fi
* Fri Oct 14 2016 Clement Oudot <clem.oudot@gmail.com> - 1.9.6-1
- Update to 1.9.6
* Mon Oct 10 2016 Clement Oudot <clem.oudot@gmail.com> - 1.4.11-1
- Update to 1.4.11
* Wed Jul 13 2016 Clement Oudot <clem.oudot@gmail.com> - 1.9.5-1
- Update to 1.9.5
* Wed Jul 13 2016 Clement Oudot <clem.oudot@gmail.com> - 1.4.10-1
- Update to 1.4.10
* Tue Jun 14 2016 Clement Oudot <clem.oudot@gmail.com> - 1.9.4-1
- Update to 1.9.4
* Tue Jun 07 2016 Clement Oudot <clem.oudot@gmail.com> - 1.9.3-1
- Update to 1.9.3
* Fri Jun 03 2016 Clement Oudot <clem.oudot@gmail.com> - 1.4.9-1
- Update to 1.4.9
* Sun May 01 2016 Clement Oudot <clem.oudot@gmail.com> - 1.9.2-1
- Update to 1.9.2
* Wed Apr 27 2016 Clement Oudot <clem.oudot@gmail.com> - 1.4.8-1
- Update to 1.4.8
* Thu Mar 31 2016 Clement Oudot <clem.oudot@gmail.com> - 1.9.1-1
- Update to 1.9.1
* Thu Mar 17 2016 Clement Oudot <clem.oudot@gmail.com> - 1.4.7-1
- Update to 1.4.7
* Wed Mar 02 2016 Clement Oudot <clem.oudot@gmail.com> - 1.9.0-1
- Update to 1.9.0