Use activation rule (#1689)
This commit is contained in:
parent
547a688c28
commit
aea313e2e6
|
@ -24,7 +24,7 @@ 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)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node)|S(?:erviceMetaDataAuthnContext|torageOptions))|penIdExportedVars)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars)|c(?:as(?:S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions)|A(?:ppMetaData(?:(?:ExportedVar|Option)s|Node)|ttributes))|(?:ustomAddParam|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|howLanguages|slByAjax)|o(?:idc(?:ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken)|RPMetaDataOptions(?:LogoutSessionRequired|BypassConsent))|ldNotifFormat)|p(?:ortal(?:ErrorOn(?:ExpiredSession|MailNotFound)|DisplayRe(?:setPassword|gister)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|RequireOldPassword|ForceAuthn|AntiFrame)|roxyUseSoap)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl)|oginHistoryEnabled)|c(?:a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:User(?:Display(?:PersistentInfo|EmptyValues))?|State|XSS)|da)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonation(?:SkipEmptyValue|MergeSSOgroup)s)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|no(?:tif(?:ication(?:Server)?|y(?:Deleted|Other))|AjaxHook)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|(?:(?:rest(?:Session|Config)|wsdl)Serv|activeTim)er|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs)|dbiDynamicHashEnabled|bruteForceProtection|favApps)$/;
|
||||
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|howLanguages|slByAjax)|o(?:idc(?:ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken)|RPMetaDataOptions(?:LogoutSessionRequired|BypassConsent))|ldNotifFormat)|p(?:ortal(?:ErrorOn(?:ExpiredSession|MailNotFound)|DisplayRe(?:setPassword|gister)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|RequireOldPassword|ForceAuthn|AntiFrame)|roxyUseSoap)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl)|oginHistoryEnabled)|c(?:a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:User(?:Display(?:PersistentInfo|EmptyValues))?|State|XSS)|da)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonation(?:SkipEmptyValue|MergeSSOgroup)s)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|no(?:tif(?:ication(?:Server)?|y(?:Deleted|Other))|AjaxHook)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|(?:(?:rest(?:Session|Config)|wsdl)Serv|activeTim)er|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs)|dbiDynamicHashEnabled|bruteForceProtection)$/;
|
||||
|
||||
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );
|
||||
|
||||
|
|
|
@ -57,8 +57,7 @@ sub defaultValues {
|
|||
'facebookExportedVars' => {},
|
||||
'facebookUserField' => 'id',
|
||||
'failedLoginNumber' => 5,
|
||||
'favApps' => 1,
|
||||
'favAppsMaxNumber' => 5,
|
||||
'favAppsMaxNumber' => 3,
|
||||
'formTimeout' => 120,
|
||||
'globalStorage' => 'Apache::Session::File',
|
||||
'globalStorageOptions' => {
|
||||
|
@ -192,6 +191,7 @@ sub defaultValues {
|
|||
'portalCheckLogins' => 1,
|
||||
'portalDisplayAppslist' => 1,
|
||||
'portalDisplayChangePassword' => '$_auth =~ /^(LDAP|DBI|Demo)$/',
|
||||
'portalDisplayFavApps' => 1,
|
||||
'portalDisplayLoginHistory' => 1,
|
||||
'portalDisplayLogout' => 1,
|
||||
'portalDisplayOidcConsents' => '$_oidcConnectedRP',
|
||||
|
|
|
@ -1144,12 +1144,8 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
|
|||
'default' => 5,
|
||||
'type' => 'int'
|
||||
},
|
||||
'favApps' => {
|
||||
'default' => 1,
|
||||
'type' => 'bool'
|
||||
},
|
||||
'favAppsMaxNumber' => {
|
||||
'default' => 5,
|
||||
'default' => 3,
|
||||
'type' => 'int'
|
||||
},
|
||||
'formTimeout' => {
|
||||
|
@ -2258,6 +2254,10 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
|
|||
'default' => '$_auth =~ /^(LDAP|DBI|Demo)$/',
|
||||
'type' => 'boolOrExpr'
|
||||
},
|
||||
'portalDisplayFavApps' => {
|
||||
'default' => 1,
|
||||
'type' => 'boolOrExpr'
|
||||
},
|
||||
'portalDisplayLoginHistory' => {
|
||||
'default' => 1,
|
||||
'type' => 'boolOrExpr'
|
||||
|
|
|
@ -446,18 +446,18 @@ sub attributes {
|
|||
documentation => 'Display session empty values',
|
||||
flags => 'p',
|
||||
},
|
||||
favApps => {
|
||||
default => 1,
|
||||
type => 'bool',
|
||||
documentation => 'Enable favorite Apps',
|
||||
flags => 'p',
|
||||
},
|
||||
favAppsMaxNumber => {
|
||||
default => 5,
|
||||
default => 3,
|
||||
type => 'int',
|
||||
documentation => 'Maximum favorite Apps number',
|
||||
flags => 'p',
|
||||
},
|
||||
portalDisplayFavApps => {
|
||||
type => 'boolOrExpr',
|
||||
default => 1,
|
||||
documentation => 'Display favorite applications tab in portal',
|
||||
flags => 'p',
|
||||
},
|
||||
impersonationMergeSSOgroups => {
|
||||
default => 0,
|
||||
type => 'bool',
|
||||
|
|
|
@ -559,6 +559,15 @@ sub tree {
|
|||
'stayConnected',
|
||||
'portalStatus',
|
||||
'upgradeSession',
|
||||
{
|
||||
title => 'favApps',
|
||||
help => 'favapps.html',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'portalDisplayFavApps',
|
||||
'favAppsMaxNumber',
|
||||
]
|
||||
},
|
||||
{
|
||||
title => 'portalServers',
|
||||
help => 'portalservers.html',
|
||||
|
@ -649,15 +658,6 @@ sub tree {
|
|||
'checkUserDisplayEmptyValues',
|
||||
]
|
||||
},
|
||||
{
|
||||
title => 'appsFav',
|
||||
help => 'favapps.html',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'favApps',
|
||||
'favAppsMaxNumber',
|
||||
]
|
||||
},
|
||||
{
|
||||
title => 'impersonation',
|
||||
help => 'impersonation.html',
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -11,6 +11,7 @@ use JSON;
|
|||
use Data::Dumper;
|
||||
|
||||
has skinRules => ( is => 'rw' );
|
||||
has favAppsRule => ( is => 'rw', default => sub { 1 } );
|
||||
|
||||
sub displayInit {
|
||||
my ($self) = @_;
|
||||
|
@ -29,6 +30,18 @@ sub displayInit {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Parse FavApps activation rule
|
||||
$self->logger->debug(
|
||||
"FavApps activation rule -> " . $self->conf->{portalDisplayFavApps} );
|
||||
my $rule =
|
||||
HANDLER->buildSub( HANDLER->substitute( $self->conf->{portalDisplayFavApps} ) );
|
||||
unless ($rule) {
|
||||
$self->error(
|
||||
"Bad FavApps activation rule -> " . HANDLER->tsv->{jail}->error );
|
||||
return 0;
|
||||
}
|
||||
$self->favAppsRule($rule);
|
||||
}
|
||||
|
||||
# Call portal process and set template parameters
|
||||
|
@ -206,6 +219,7 @@ sub display {
|
|||
PING => $self->conf->{portalPingInterval},
|
||||
REQUIRE_OLDPASSWORD => $self->conf->{portalRequireOldPassword},
|
||||
HIDE_OLDPASSWORD => 0,
|
||||
FAVAPPS => $self->favAppsRule->( $req, $req->userData ),
|
||||
$self->menu->params($req),
|
||||
(
|
||||
$req->data->{customScript}
|
||||
|
|
|
@ -18,7 +18,7 @@ has menuModules => (
|
|||
builder => sub {
|
||||
my $conf = $_[0]->{conf};
|
||||
my @res;
|
||||
foreach (qw(Appslist ChangePassword LoginHistory OidcConsents Logout)) {
|
||||
foreach (qw(FavApps Appslist ChangePassword LoginHistory OidcConsents Logout)) {
|
||||
my $cond = $conf->{"portalDisplay$_"} // 1;
|
||||
$_[0]->p->logger->debug("Evaluate condition $cond for module $_");
|
||||
my $tmp =
|
||||
|
@ -62,6 +62,8 @@ sub params {
|
|||
my @defaultTabs = (qw/appslist password logout loginHistory oidcConsents/);
|
||||
my @customTabs = split( /,\s*/, $self->{conf}->{customMenuTabs} || '' );
|
||||
|
||||
push @defaultTabs, 'favApps' if $self->{conf}->{favApps};
|
||||
|
||||
# Tab to display
|
||||
# Get the tab URL parameter
|
||||
|
||||
|
@ -101,7 +103,7 @@ sub params {
|
|||
$res{DISPLAY_TAB} = $req->param("tab");
|
||||
}
|
||||
else {
|
||||
$res{DISPLAY_TAB} = "appslist";
|
||||
$res{DISPLAY_TAB} = $self->{conf}->{favApps} ? "favApps" : "appslist";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ our @pList = (
|
|||
portalForceAuthn => '::Plugins::ForceAuthn',
|
||||
checkUser => '::Plugins::CheckUser',
|
||||
impersonationRule => '::Plugins::Impersonation',
|
||||
favApps => '::Plugins::FavApps',
|
||||
portalDisplayFavApps => '::Plugins::FavApps',
|
||||
);
|
||||
|
||||
##@method list enabledPlugins
|
||||
|
|
|
@ -3,33 +3,58 @@ package Lemonldap::NG::Portal::Plugins::FavApps;
|
|||
use strict;
|
||||
use Mouse;
|
||||
use JSON qw(from_json to_json);
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_BADCREDENTIALS
|
||||
PE_TOKENEXPIRED
|
||||
PE_NOTOKEN
|
||||
PE_MALFORMEDUSER
|
||||
);
|
||||
|
||||
our $VERSION = '2.1.0';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
||||
|
||||
# INITIALIZATION
|
||||
has rule => ( is => 'rw', default => sub { 1 } );
|
||||
|
||||
sub init {
|
||||
my $self = shift;
|
||||
my $hd = $self->p->HANDLER;
|
||||
|
||||
$self->addAuthRoute( favapps => 'register', ['POST'] );
|
||||
$self->addAuthRoute( favapps => 'read', ['GET'] );
|
||||
|
||||
# Parse activation rule
|
||||
$self->logger->debug(
|
||||
"FavApps activation rule -> " . $self->conf->{portalDisplayFavApps} );
|
||||
my $rule =
|
||||
$hd->buildSub( $hd->substitute( $self->conf->{portalDisplayFavApps} ) );
|
||||
unless ($rule) {
|
||||
$self->error(
|
||||
"Bad FavApps activation rule -> " . $hd->tsv->{jail}->error );
|
||||
return 0;
|
||||
}
|
||||
$self->rule($rule);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# RUNNING METHOD
|
||||
|
||||
# RUNNING METHODS
|
||||
sub register {
|
||||
my ( $self, $req ) = @_;
|
||||
my $user = $req->userData->{ $self->conf->{whatToTrace} };
|
||||
|
||||
# Check activation rule
|
||||
unless ( $self->rule->( $req, $req->userData ) ) {
|
||||
$self->userLogger->warn(
|
||||
'FavApps requested by an unauthorized user ('
|
||||
. $req->{user}
|
||||
. ')' );
|
||||
$self->logger->debug('FavApps not authorized');
|
||||
return [
|
||||
200,
|
||||
[
|
||||
'Content-Type' => 'application/json',
|
||||
'Content-Length' => 11,
|
||||
],
|
||||
['{"error":0}']
|
||||
];
|
||||
}
|
||||
|
||||
my ( $app, $result );
|
||||
unless ( $app = $req->param('app') ) {
|
||||
return $self->p->sendError( $req, 'Missing App. URI', 400 );
|
||||
|
@ -83,7 +108,6 @@ sub register {
|
|||
"Max number of favorite apps reached for $user");
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
200,
|
||||
[
|
||||
|
|
|
@ -27,14 +27,6 @@
|
|||
<span trspan="yourApps">Your applications</span>
|
||||
</span></a></li>
|
||||
</TMPL_IF>
|
||||
<!--
|
||||
<TMPL_IF NAME="favApps">
|
||||
<li class="nav-item"><a class="nav-link" href="#favApps"><span>
|
||||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/application_cascade.png" width="16" height="16" alt="favApps" />
|
||||
<span trspan="yourFavApps">Your favorites applications</span>
|
||||
</span></a></li>
|
||||
</TMPL_IF>
|
||||
-->
|
||||
<TMPL_IF NAME="ChangePassword">
|
||||
<li class="nav-item"><a class="nav-link" href="#password"><span>
|
||||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/vcard_edit.png" width="16" height="16" alt="password" />
|
||||
|
@ -115,9 +107,11 @@
|
|||
|
||||
<!-- Application -->
|
||||
<div class="col-md-4">
|
||||
<div>
|
||||
<img class="star" appuri="<TMPL_VAR NAME="appuri">" title="<TMPL_VAR NAME="appname">" logo="<TMPL_VAR NAME="STATIC_PREFIX">common/apps/<TMPL_VAR NAME="applogo">" desc="<TMPL_VAR NAME="appdesc">" src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/star0.png"/>
|
||||
</div>
|
||||
<TMPL_IF NAME="FAVAPPS">
|
||||
<div>
|
||||
<img class="star" appuri="<TMPL_VAR NAME="appuri">" title="<TMPL_VAR NAME="appname">" logo="<TMPL_VAR NAME="STATIC_PREFIX">common/apps/<TMPL_VAR NAME="applogo">" desc="<TMPL_VAR NAME="appdesc">" src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/star0.png"/>
|
||||
</div>
|
||||
</TMPL_IF>
|
||||
<div class="application <TMPL_VAR NAME="appid"> card">
|
||||
|
||||
<a href="<TMPL_VAR NAME="appuri">" title="<TMPL_VAR NAME="appname">" >
|
||||
|
|
Loading…
Reference in New Issue