Split notifications (XML vs JSON) [#868]
This commit is contained in:
parent
f6665c2d41
commit
61fd463f45
|
@ -2,19 +2,21 @@ package Lemonldap::NG::Common::Notifications;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
use XML::LibXML;
|
|
||||||
|
|
||||||
our $VERSION = '2.0.0';
|
our $VERSION = '2.0.0';
|
||||||
|
|
||||||
extends 'Lemonldap::NG::Common::Module';
|
extends 'Lemonldap::NG::Common::Module';
|
||||||
|
|
||||||
# XML parser. TODO: replace this by JSON
|
sub import {
|
||||||
has parser => (
|
if ( $_[1] eq 'XML' ) {
|
||||||
is => 'rw',
|
extends 'Lemonldap::NG::Common::Notifications::XML',
|
||||||
builder => sub {
|
'Lemonldap::NG::Common::Module';
|
||||||
return XML::LibXML->new();
|
|
||||||
}
|
}
|
||||||
);
|
else {
|
||||||
|
extends 'Lemonldap::NG::Common::Notifications::JSON',
|
||||||
|
'Lemonldap::NG::Common::Module';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
has notifField => (
|
has notifField => (
|
||||||
is => 'rw',
|
is => 'rw',
|
||||||
|
@ -40,111 +42,4 @@ sub getNotifications {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check XML datas and insert new notifications.
|
|
||||||
# @param $xml XML string containing notification
|
|
||||||
# @return number of notifications done
|
|
||||||
sub newNotification {
|
|
||||||
my ( $self, $xml ) = @_;
|
|
||||||
eval { $xml = $self->parser->parse_string($xml); };
|
|
||||||
if ($@) {
|
|
||||||
$self->lmLog( "Unable to read XML file : $@", 'error' );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
my @notifs;
|
|
||||||
my ( $version, $encoding ) = ( $xml->version(), $xml->encoding() );
|
|
||||||
foreach
|
|
||||||
my $notif ( $xml->documentElement->getElementsByTagName('notification') )
|
|
||||||
{
|
|
||||||
my @datas = ();
|
|
||||||
|
|
||||||
# Mandatory information
|
|
||||||
foreach (qw(date uid reference)) {
|
|
||||||
my $tmp;
|
|
||||||
unless ( $tmp = $notif->getAttribute($_) ) {
|
|
||||||
$self->lmLog( "Attribute $_ is missing", 'error' );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
push @datas, $tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Other information
|
|
||||||
foreach (qw(condition)) {
|
|
||||||
my $tmp;
|
|
||||||
if ( $tmp = $notif->getAttribute($_) ) {
|
|
||||||
push @datas, $tmp;
|
|
||||||
}
|
|
||||||
else { push @datas, ""; }
|
|
||||||
}
|
|
||||||
|
|
||||||
my $result = XML::LibXML::Document->new( $version, $encoding );
|
|
||||||
my $root = XML::LibXML::Element->new('root');
|
|
||||||
$root->appendChild($notif);
|
|
||||||
$result->setDocumentElement($root);
|
|
||||||
push @notifs, [ @datas, $result ];
|
|
||||||
}
|
|
||||||
my $tmp = $self->{type};
|
|
||||||
my $count;
|
|
||||||
foreach (@notifs) {
|
|
||||||
$count++;
|
|
||||||
my ( $r, $err ) = $self->newNotif(@$_);
|
|
||||||
die "$err" unless ($r);
|
|
||||||
}
|
|
||||||
return $count;
|
|
||||||
}
|
|
||||||
|
|
||||||
## Delete notifications for the connected user
|
|
||||||
## @param $uid of the user
|
|
||||||
## @param $myref notification's reference
|
|
||||||
## @return number of deleted notifications
|
|
||||||
sub deleteNotification {
|
|
||||||
my ( $self, $uid, $myref ) = @_;
|
|
||||||
my @data;
|
|
||||||
|
|
||||||
# Check input parameters
|
|
||||||
unless ( $uid and $myref ) {
|
|
||||||
$self->lmLog(
|
|
||||||
"SOAP service deleteNotification called without all parameters",
|
|
||||||
'error' );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$self->lmLog(
|
|
||||||
"SOAP service deleteNotification called for uid $uid and reference $myref",
|
|
||||||
'debug'
|
|
||||||
);
|
|
||||||
|
|
||||||
# Get notifications
|
|
||||||
my $user = $self->get($uid);
|
|
||||||
|
|
||||||
# Return 0 if no files were found
|
|
||||||
return 0 unless ($user);
|
|
||||||
|
|
||||||
# Counting
|
|
||||||
my $count = 0;
|
|
||||||
|
|
||||||
foreach my $ref ( keys %$user ) {
|
|
||||||
my $xml = $self->parser->parse_string( $user->{$ref} );
|
|
||||||
|
|
||||||
# Browse notification in file
|
|
||||||
foreach my $notif (
|
|
||||||
$xml->documentElement->getElementsByTagName('notification') )
|
|
||||||
{
|
|
||||||
|
|
||||||
# Get notification's data
|
|
||||||
if ( $notif->getAttribute('reference') eq $myref ) {
|
|
||||||
push @data, $ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Delete the notification (really)
|
|
||||||
foreach (@data) {
|
|
||||||
if ( $self->purge( $_, 1 ) ) {
|
|
||||||
$self->lmLog( "Notification $_ was removed.", 'debug' );
|
|
||||||
$count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $count;
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -14,6 +14,10 @@ use Encode;
|
||||||
our $VERSION = '2.0.0';
|
our $VERSION = '2.0.0';
|
||||||
|
|
||||||
extends 'Lemonldap::NG::Common::Notifications';
|
extends 'Lemonldap::NG::Common::Notifications';
|
||||||
|
sub import {
|
||||||
|
shift;
|
||||||
|
return Lemonldap::NG::Common::Notifications->import(@_)
|
||||||
|
}
|
||||||
|
|
||||||
has dbiTable => (
|
has dbiTable => (
|
||||||
is => 'ro',
|
is => 'ro',
|
||||||
|
@ -28,7 +32,7 @@ has dbiChain => (
|
||||||
has dbiUser => (
|
has dbiUser => (
|
||||||
is => 'ro',
|
is => 'ro',
|
||||||
default => sub {
|
default => sub {
|
||||||
$_[0]->p->lmLog( 'Warning: "dbiUser" parameter is not set', 'warn' );
|
$_[0]->{p}->lmLog( 'Warning: "dbiUser" parameter is not set', 'warn' );
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -12,6 +12,11 @@ use MIME::Base64;
|
||||||
our $VERSION = '2.0.0';
|
our $VERSION = '2.0.0';
|
||||||
|
|
||||||
extends 'Lemonldap::NG::Common::Notifications';
|
extends 'Lemonldap::NG::Common::Notifications';
|
||||||
|
sub import {
|
||||||
|
shift;
|
||||||
|
return Lemonldap::NG::Common::Notifications->import(@_)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
has dirName => ( is => 'ro', required => 1 );
|
has dirName => ( is => 'ro', required => 1 );
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,10 @@ use utf8;
|
||||||
our $VERSION = '2.0.0';
|
our $VERSION = '2.0.0';
|
||||||
|
|
||||||
extends 'Lemonldap::NG::Common::Notifications';
|
extends 'Lemonldap::NG::Common::Notifications';
|
||||||
|
sub import {
|
||||||
|
shift;
|
||||||
|
return Lemonldap::NG::Common::Notifications->import(@_)
|
||||||
|
}
|
||||||
|
|
||||||
has ldapServer => (
|
has ldapServer => (
|
||||||
is => 'ro',
|
is => 'ro',
|
||||||
|
|
122
lemonldap-ng-common/lib/Lemonldap/NG/Common/Notifications/XML.pm
Normal file
122
lemonldap-ng-common/lib/Lemonldap/NG/Common/Notifications/XML.pm
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
package Lemonldap::NG::Common::Notifications::XML;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use Mouse;
|
||||||
|
use XML::LibXML;
|
||||||
|
|
||||||
|
# XML parser
|
||||||
|
has parser => (
|
||||||
|
is => 'rw',
|
||||||
|
builder => sub {
|
||||||
|
return XML::LibXML->new();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
# Check XML datas and insert new notifications.
|
||||||
|
# @param $xml XML string containing notification
|
||||||
|
# @return number of notifications done
|
||||||
|
sub newNotification {
|
||||||
|
my ( $self, $xml ) = @_;
|
||||||
|
eval { $xml = $self->parser->parse_string($xml); };
|
||||||
|
if ($@) {
|
||||||
|
$self->lmLog( "Unable to read XML file : $@", 'error' );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
my @notifs;
|
||||||
|
my ( $version, $encoding ) = ( $xml->version(), $xml->encoding() );
|
||||||
|
foreach
|
||||||
|
my $notif ( $xml->documentElement->getElementsByTagName('notification') )
|
||||||
|
{
|
||||||
|
my @datas = ();
|
||||||
|
|
||||||
|
# Mandatory information
|
||||||
|
foreach (qw(date uid reference)) {
|
||||||
|
my $tmp;
|
||||||
|
unless ( $tmp = $notif->getAttribute($_) ) {
|
||||||
|
$self->lmLog( "Attribute $_ is missing", 'error' );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
push @datas, $tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Other information
|
||||||
|
foreach (qw(condition)) {
|
||||||
|
my $tmp;
|
||||||
|
if ( $tmp = $notif->getAttribute($_) ) {
|
||||||
|
push @datas, $tmp;
|
||||||
|
}
|
||||||
|
else { push @datas, ""; }
|
||||||
|
}
|
||||||
|
|
||||||
|
my $result = XML::LibXML::Document->new( $version, $encoding );
|
||||||
|
my $root = XML::LibXML::Element->new('root');
|
||||||
|
$root->appendChild($notif);
|
||||||
|
$result->setDocumentElement($root);
|
||||||
|
push @notifs, [ @datas, $result ];
|
||||||
|
}
|
||||||
|
my $tmp = $self->{type};
|
||||||
|
my $count;
|
||||||
|
foreach (@notifs) {
|
||||||
|
$count++;
|
||||||
|
my ( $r, $err ) = $self->newNotif(@$_);
|
||||||
|
die "$err" unless ($r);
|
||||||
|
}
|
||||||
|
return $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
## Delete notifications for the connected user
|
||||||
|
## @param $uid of the user
|
||||||
|
## @param $myref notification's reference
|
||||||
|
## @return number of deleted notifications
|
||||||
|
sub deleteNotification {
|
||||||
|
my ( $self, $uid, $myref ) = @_;
|
||||||
|
my @data;
|
||||||
|
|
||||||
|
# Check input parameters
|
||||||
|
unless ( $uid and $myref ) {
|
||||||
|
$self->lmLog(
|
||||||
|
"SOAP service deleteNotification called without all parameters",
|
||||||
|
'error' );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->lmLog(
|
||||||
|
"SOAP service deleteNotification called for uid $uid and reference $myref",
|
||||||
|
'debug'
|
||||||
|
);
|
||||||
|
|
||||||
|
# Get notifications
|
||||||
|
my $user = $self->get($uid);
|
||||||
|
|
||||||
|
# Return 0 if no files were found
|
||||||
|
return 0 unless ($user);
|
||||||
|
|
||||||
|
# Counting
|
||||||
|
my $count = 0;
|
||||||
|
|
||||||
|
foreach my $ref ( keys %$user ) {
|
||||||
|
my $xml = $self->parser->parse_string( $user->{$ref} );
|
||||||
|
|
||||||
|
# Browse notification in file
|
||||||
|
foreach my $notif (
|
||||||
|
$xml->documentElement->getElementsByTagName('notification') )
|
||||||
|
{
|
||||||
|
|
||||||
|
# Get notification's data
|
||||||
|
if ( $notif->getAttribute('reference') eq $myref ) {
|
||||||
|
push @data, $ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Delete the notification (really)
|
||||||
|
foreach (@data) {
|
||||||
|
if ( $self->purge( $_, 1 ) ) {
|
||||||
|
$self->lmLog( "Notification $_ was removed.", 'debug' );
|
||||||
|
$count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
|
@ -31,9 +31,7 @@ sub init {
|
||||||
my ( $self, $args ) = @_;
|
my ( $self, $args ) = @_;
|
||||||
$args ||= {};
|
$args ||= {};
|
||||||
|
|
||||||
my $conf = $self->confAcc;
|
if ( my $localconf = $self->confAcc->getLocalConf(MANAGERSECTION) ) {
|
||||||
|
|
||||||
if ( my $localconf = $conf->getLocalConf(MANAGERSECTION) ) {
|
|
||||||
$self->{$_} = $args->{$_} // $localconf->{$_}
|
$self->{$_} = $args->{$_} // $localconf->{$_}
|
||||||
foreach ( keys %$localconf );
|
foreach ( keys %$localconf );
|
||||||
}
|
}
|
||||||
|
@ -57,10 +55,11 @@ sub init {
|
||||||
split( /[,\s]+/, $self->{enabledModules} );
|
split( /[,\s]+/, $self->{enabledModules} );
|
||||||
extends 'Lemonldap::NG::Handler::PSGI::Router', @enabledModules;
|
extends 'Lemonldap::NG::Handler::PSGI::Router', @enabledModules;
|
||||||
my @working;
|
my @working;
|
||||||
|
my $conf = $self->confAcc->getConf;
|
||||||
for ( my $i = 0 ; $i < @enabledModules ; $i++ ) {
|
for ( my $i = 0 ; $i < @enabledModules ; $i++ ) {
|
||||||
my $mod = $enabledModules[$i];
|
my $mod = $enabledModules[$i];
|
||||||
no strict 'refs';
|
no strict 'refs';
|
||||||
if ( &{"${mod}::addRoutes"}($self) ) {
|
if ( &{"${mod}::addRoutes"}($self,$conf) ) {
|
||||||
$self->lmLog( "Module $mod enabled", 'debug' );
|
$self->lmLog( "Module $mod enabled", 'debug' );
|
||||||
push @working, $mod;
|
push @working, $mod;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1720,6 +1720,10 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
|
||||||
'oidcStorageOptions' => {
|
'oidcStorageOptions' => {
|
||||||
'type' => 'keyTextContainer'
|
'type' => 'keyTextContainer'
|
||||||
},
|
},
|
||||||
|
'oldNotifFormat' => {
|
||||||
|
'default' => 0,
|
||||||
|
'type' => 'bool'
|
||||||
|
},
|
||||||
'openIdAttr' => {
|
'openIdAttr' => {
|
||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
},
|
},
|
||||||
|
|
|
@ -660,6 +660,11 @@ sub attributes {
|
||||||
},
|
},
|
||||||
|
|
||||||
# Notification
|
# Notification
|
||||||
|
oldNotifFormat => {
|
||||||
|
type => 'bool',
|
||||||
|
default => 0,
|
||||||
|
documentation => 'Use old XML format',
|
||||||
|
},
|
||||||
notificationWildcard => {
|
notificationWildcard => {
|
||||||
type => 'text',
|
type => 'text',
|
||||||
default => 'allusers',
|
default => 'allusers',
|
||||||
|
|
|
@ -534,6 +534,7 @@ sub tree {
|
||||||
help => 'notifications.html',
|
help => 'notifications.html',
|
||||||
nodes => [
|
nodes => [
|
||||||
'notification',
|
'notification',
|
||||||
|
'oldNotifFormat',
|
||||||
'notificationStorage',
|
'notificationStorage',
|
||||||
'notificationStorageOptions',
|
'notificationStorageOptions',
|
||||||
'notificationWildcard',
|
'notificationWildcard',
|
||||||
|
|
|
@ -27,7 +27,7 @@ our $VERSION = '2.0.0';
|
||||||
use constant defaultRoute => 'manager.html';
|
use constant defaultRoute => 'manager.html';
|
||||||
|
|
||||||
sub addRoutes {
|
sub addRoutes {
|
||||||
my $self = shift;
|
my($self,$conf) = @_;
|
||||||
|
|
||||||
# HTML template
|
# HTML template
|
||||||
$self->addRoute( 'manager.html', undef, ['GET'] )
|
$self->addRoute( 'manager.html', undef, ['GET'] )
|
||||||
|
|
|
@ -7,7 +7,7 @@ use Mouse;
|
||||||
use Lemonldap::NG::Common::Conf::Constants;
|
use Lemonldap::NG::Common::Conf::Constants;
|
||||||
use Lemonldap::NG::Common::PSGI::Constants;
|
use Lemonldap::NG::Common::PSGI::Constants;
|
||||||
use Lemonldap::NG::Common::Conf::ReConstants;
|
use Lemonldap::NG::Common::Conf::ReConstants;
|
||||||
use Lemonldap::NG::Common::Notifications;
|
require Lemonldap::NG::Common::Notifications;
|
||||||
|
|
||||||
use feature 'state';
|
use feature 'state';
|
||||||
|
|
||||||
|
@ -24,7 +24,14 @@ has _notifAccess => ( is => 'rw' );
|
||||||
use constant defaultRoute => 'notifications.html';
|
use constant defaultRoute => 'notifications.html';
|
||||||
|
|
||||||
sub addRoutes {
|
sub addRoutes {
|
||||||
my $self = shift;
|
my($self,$conf) = @_;
|
||||||
|
|
||||||
|
if($conf->{oldNotifFormat}) {
|
||||||
|
Lemonldap::NG::Common::Notifications->import('XML');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Lemonldap::NG::Common::Notifications->import('JSON');
|
||||||
|
}
|
||||||
|
|
||||||
unless ( $self->notifAccess ) {
|
unless ( $self->notifAccess ) {
|
||||||
$self->addRoute( 'notifications.html', 'notEnabled', ['GET'] );
|
$self->addRoute( 'notifications.html', 'notEnabled', ['GET'] );
|
||||||
|
|
|
@ -25,7 +25,7 @@ our $VERSION = '2.0.0';
|
||||||
use constant defaultRoute => 'sessions.html';
|
use constant defaultRoute => 'sessions.html';
|
||||||
|
|
||||||
sub addRoutes {
|
sub addRoutes {
|
||||||
my $self = shift;
|
my($self,$conf) = @_;
|
||||||
|
|
||||||
# HTML template
|
# HTML template
|
||||||
$self->addRoute( 'sessions.html', undef, ['GET'] )
|
$self->addRoute( 'sessions.html', undef, ['GET'] )
|
||||||
|
@ -39,11 +39,6 @@ sub addRoutes {
|
||||||
['DELETE']
|
['DELETE']
|
||||||
);
|
);
|
||||||
|
|
||||||
my $conf = $self->confAcc->getConf(
|
|
||||||
{ localPrm => $self->confAcc->getLocalConf(SESSIONSEXPLORERSECTION) } );
|
|
||||||
#
|
|
||||||
# Return unless configuration is available
|
|
||||||
return 0 unless ($conf);
|
|
||||||
$self->setTypes($conf);
|
$self->setTypes($conf);
|
||||||
|
|
||||||
$self->{ipField} ||= 'ipAddr';
|
$self->{ipField} ||= 'ipAddr';
|
||||||
|
|
|
@ -461,6 +461,7 @@
|
||||||
"oidcServiceAllowImplicitFlow": "Implicit Flow",
|
"oidcServiceAllowImplicitFlow": "Implicit Flow",
|
||||||
"oidcServiceAllowHybridFlow": "Hybrid Flow",
|
"oidcServiceAllowHybridFlow": "Hybrid Flow",
|
||||||
"ok": "OK",
|
"ok": "OK",
|
||||||
|
"oldNotifFormat": "Use old XML format",
|
||||||
"openIdAttr": "OpenID login",
|
"openIdAttr": "OpenID login",
|
||||||
"openIdAuthnLevel": "Authentication level",
|
"openIdAuthnLevel": "Authentication level",
|
||||||
"openIdExportedVars": "Exported variables",
|
"openIdExportedVars": "Exported variables",
|
||||||
|
|
|
@ -461,6 +461,7 @@
|
||||||
"oidcServiceAllowImplicitFlow": "Implicit Flow",
|
"oidcServiceAllowImplicitFlow": "Implicit Flow",
|
||||||
"oidcServiceAllowHybridFlow": "Hybrid Flow",
|
"oidcServiceAllowHybridFlow": "Hybrid Flow",
|
||||||
"ok": "OK",
|
"ok": "OK",
|
||||||
|
"oldNotifFormat": "Utiliser l'ancien format XML",
|
||||||
"openIdAttr": "Identifiant OpenID",
|
"openIdAttr": "Identifiant OpenID",
|
||||||
"openIdAuthnLevel": "Niveau d'authentification",
|
"openIdAuthnLevel": "Niveau d'authentification",
|
||||||
"openIdExportedVars": "Variables exportées",
|
"openIdExportedVars": "Variables exportées",
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -132,6 +132,7 @@
|
||||||
"_whatToTrace": "$_auth eq 'SAML' ? \"$_user\\@$_idpConfKey\" : \"$_user\""
|
"_whatToTrace": "$_auth eq 'SAML' ? \"$_user\\@$_idpConfKey\" : \"$_user\""
|
||||||
},
|
},
|
||||||
"notification": 1,
|
"notification": 1,
|
||||||
|
"oldNotifFormat": 1,
|
||||||
"notificationStorage": "File",
|
"notificationStorage": "File",
|
||||||
"notificationStorageOptions": {
|
"notificationStorageOptions": {
|
||||||
"dirName": "t/notifications"
|
"dirName": "t/notifications"
|
||||||
|
|
|
@ -2454,4 +2454,8 @@
|
||||||
"id": "cfgLog",
|
"id": "cfgLog",
|
||||||
"title": "cfgLog",
|
"title": "cfgLog",
|
||||||
"data": "Log"
|
"data": "Log"
|
||||||
|
}, {
|
||||||
|
"id": "oldNotifFormat",
|
||||||
|
"title": "oldNotifFormat",
|
||||||
|
"data": 1
|
||||||
}]
|
}]
|
||||||
|
|
|
@ -46,6 +46,8 @@ lib/Lemonldap/NG/Portal/Lib/Choice.pm
|
||||||
lib/Lemonldap/NG/Portal/Lib/DBI.pm
|
lib/Lemonldap/NG/Portal/Lib/DBI.pm
|
||||||
lib/Lemonldap/NG/Portal/Lib/LDAP.pm
|
lib/Lemonldap/NG/Portal/Lib/LDAP.pm
|
||||||
lib/Lemonldap/NG/Portal/Lib/Net/LDAP.pm
|
lib/Lemonldap/NG/Portal/Lib/Net/LDAP.pm
|
||||||
|
lib/Lemonldap/NG/Portal/Lib/Notifications/JSON.pm
|
||||||
|
lib/Lemonldap/NG/Portal/Lib/Notifications/XML.pm
|
||||||
lib/Lemonldap/NG/Portal/Lib/OneTimeToken.pm
|
lib/Lemonldap/NG/Portal/Lib/OneTimeToken.pm
|
||||||
lib/Lemonldap/NG/Portal/Lib/OpenID/Server.pm
|
lib/Lemonldap/NG/Portal/Lib/OpenID/Server.pm
|
||||||
lib/Lemonldap/NG/Portal/Lib/OpenID/SREG.pm
|
lib/Lemonldap/NG/Portal/Lib/OpenID/SREG.pm
|
||||||
|
@ -333,7 +335,6 @@ site/templates/pastel/yubikeyform.tpl
|
||||||
t/01-AuthDemo.t
|
t/01-AuthDemo.t
|
||||||
t/02-Password-Demo.t
|
t/02-Password-Demo.t
|
||||||
t/03-XSS-protection.t
|
t/03-XSS-protection.t
|
||||||
t/04-Notification-File.t
|
|
||||||
t/20-Auth-and-password-DBI.t
|
t/20-Auth-and-password-DBI.t
|
||||||
t/21-Auth-and-password-LDAP.t
|
t/21-Auth-and-password-LDAP.t
|
||||||
t/22-Auth-and-password-AD.t
|
t/22-Auth-and-password-AD.t
|
||||||
|
@ -361,6 +362,7 @@ t/34-Auth-Proxy-and-SOAP-Server.t
|
||||||
t/35-REST-sessions-with-REST-server.t
|
t/35-REST-sessions-with-REST-server.t
|
||||||
t/35-SOAP-sessions-with-SOAP-server.t
|
t/35-SOAP-sessions-with-SOAP-server.t
|
||||||
t/40-Notifications-DBI.t
|
t/40-Notifications-DBI.t
|
||||||
|
t/40-Notifications-File.t
|
||||||
t/41-Captcha.t
|
t/41-Captcha.t
|
||||||
t/41-Token.t
|
t/41-Token.t
|
||||||
t/42-Register-Demo-with-captcha.t
|
t/42-Register-Demo-with-captcha.t
|
||||||
|
|
|
@ -0,0 +1,256 @@
|
||||||
|
package Lemonldap::NG::Portal::Lib::Notifications::XML;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use Mouse;
|
||||||
|
use XML::LibXML;
|
||||||
|
use XML::LibXSLT;
|
||||||
|
|
||||||
|
our $VERSION = '2.0.0';
|
||||||
|
|
||||||
|
# Lemonldap::NG::Portal::Main::Plugin provides addAuthRoute() and
|
||||||
|
# addUnauthRoute() methods in addition of Lemonldap::NG::Common::Module.
|
||||||
|
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
||||||
|
|
||||||
|
# PROPERTIES
|
||||||
|
|
||||||
|
# XML parser
|
||||||
|
has parser => (
|
||||||
|
is => 'rw',
|
||||||
|
builder => sub {
|
||||||
|
return XML::LibXML->new();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
# XSLT document
|
||||||
|
has stylesheet => (
|
||||||
|
is => 'rw',
|
||||||
|
lazy => 1,
|
||||||
|
builder => sub {
|
||||||
|
my $self = $_[0];
|
||||||
|
my $xslt = XML::LibXSLT->new();
|
||||||
|
my $styleFile = (
|
||||||
|
(
|
||||||
|
$self->conf->{notificationXSLTfile}
|
||||||
|
and -e $self->conf->{notificationXSLTfile}
|
||||||
|
)
|
||||||
|
? $self->conf->{notificationXSLTfile}
|
||||||
|
: $self->conf->{templatesDir} . '/common/notification.xsl'
|
||||||
|
);
|
||||||
|
die "$styleFile not found" unless ( -e $styleFile );
|
||||||
|
return $xslt->parse_stylesheet( $self->parser->parse_file($styleFile) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
# Underlying notifications storage object (File, DBI, LDAP,...)
|
||||||
|
has notifObject => ( is => 'rw' );
|
||||||
|
|
||||||
|
# INITIALIZATION
|
||||||
|
|
||||||
|
sub init {
|
||||||
|
1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Search for notifications and if any, returns HTML fragment.
|
||||||
|
sub checkForNotifications {
|
||||||
|
my ( $self, $req ) = @_;
|
||||||
|
|
||||||
|
# Look for pending notifications in database
|
||||||
|
my $uid = $req->sessionInfo->{ $self->notifObject->notifField };
|
||||||
|
my ( $notifs, $forUser ) = $self->notifObject->getNotifications($uid);
|
||||||
|
my $form;
|
||||||
|
return 0 unless ($notifs);
|
||||||
|
|
||||||
|
# Transform notifications
|
||||||
|
my $i = 0; #Files count
|
||||||
|
foreach my $file ( values %$notifs ) {
|
||||||
|
my $xml = $self->parser->parse_string($file);
|
||||||
|
my $j = 0; #Notifications count
|
||||||
|
LOOP: foreach my $notif (
|
||||||
|
eval { $xml->documentElement->getElementsByTagName('notification') }
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
# Get the reference
|
||||||
|
my $reference = $notif->getAttribute('reference');
|
||||||
|
|
||||||
|
$self->lmLog( "Get reference $reference", 'debug' );
|
||||||
|
|
||||||
|
# Check it in session
|
||||||
|
if ( exists $req->{sessionInfo}->{"notification_$reference"} ) {
|
||||||
|
|
||||||
|
# The notification was already accepted
|
||||||
|
$self->lmLog( "Notification $reference was already accepted",
|
||||||
|
'debug' );
|
||||||
|
|
||||||
|
# Remove it from XML
|
||||||
|
$notif->unbindNode();
|
||||||
|
next LOOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check condition if any
|
||||||
|
my $condition = $notif->getAttribute('condition');
|
||||||
|
|
||||||
|
if ($condition) {
|
||||||
|
|
||||||
|
$self->lmLog( "Get condition $condition", 'debug' );
|
||||||
|
|
||||||
|
unless ( $self->p->HANDLER->safe->reval($condition) ) {
|
||||||
|
$self->lmLog( "Notification condition not accepted",
|
||||||
|
'debug' );
|
||||||
|
|
||||||
|
# Remove it from XML
|
||||||
|
$notif->unbindNode();
|
||||||
|
next LOOP;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Go to next file if no notification found
|
||||||
|
next unless $j;
|
||||||
|
$i++;
|
||||||
|
|
||||||
|
# Transform XML into HTML
|
||||||
|
my $results = $self->stylesheet->transform( $xml, start => $i );
|
||||||
|
$form .= $self->stylesheet->output_string($results);
|
||||||
|
}
|
||||||
|
if ($@) {
|
||||||
|
$self->lmLog( "Bad XML file: a notification for $uid was not done ($@)",
|
||||||
|
'warn' );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Stop here if nothing to display
|
||||||
|
return 0 unless $i;
|
||||||
|
|
||||||
|
# Returns HTML fragment
|
||||||
|
$req->id( $self->p->HANDLER->tsv->{cipher}->encrypt( $req->id ) );
|
||||||
|
return $form;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getNotifBack {
|
||||||
|
my ( $self, $req, $name ) = @_;
|
||||||
|
|
||||||
|
# Look if all notifications have been accepted. If not, redirects to
|
||||||
|
# portal
|
||||||
|
|
||||||
|
# Search for Lemonldap::NG cookie (ciphered)
|
||||||
|
my $id;
|
||||||
|
unless ( $id = $req->cookies->{ $self->{conf}->{cookieName} } ) {
|
||||||
|
return $self->p->sendError( $req, 'No cookie found', 401 );
|
||||||
|
}
|
||||||
|
$id = $self->p->HANDLER->tsv->{cipher}->decrypt($id)
|
||||||
|
or return $self->sendError( $req, 'Unable to decrypt', 500 );
|
||||||
|
|
||||||
|
# Verify that session exists
|
||||||
|
$req->userData( $self->p->HANDLER->retrieveSession($id) )
|
||||||
|
or return $self->sendError( $req, 'Unknown session', 401 );
|
||||||
|
|
||||||
|
# Restore datas
|
||||||
|
$self->p->importHandlerDatas($req);
|
||||||
|
my $uid = $req->sessionInfo->{ $self->notifObject->notifField };
|
||||||
|
|
||||||
|
my ( $notifs, $forUser ) = $self->notifObject->getNotifications($uid);
|
||||||
|
if ($notifs) {
|
||||||
|
|
||||||
|
# Get accepted notifications
|
||||||
|
my ( $refs, $checks ) = ( {}, {} );
|
||||||
|
my $prms = $req->parameters;
|
||||||
|
foreach ( keys %$prms ) {
|
||||||
|
my $v = $prms->{$_};
|
||||||
|
if (s/^reference//) {
|
||||||
|
$refs->{$v} = $_;
|
||||||
|
}
|
||||||
|
elsif ( s/^check// and /^(\d+x\d+)x(\d+)$/ and $v eq 'accepted' ) {
|
||||||
|
push @{ $checks->{$1} }, $2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my $result = 1;
|
||||||
|
foreach my $fileName ( keys %$notifs ) {
|
||||||
|
my $file = $notifs->{$fileName};
|
||||||
|
my $fileResult = 1;
|
||||||
|
my $xml = $self->parser->parse_string($file);
|
||||||
|
|
||||||
|
# Get pending notifications and verify that they have been accepted
|
||||||
|
foreach my $notif (
|
||||||
|
$xml->documentElement->getElementsByTagName('notification') )
|
||||||
|
{
|
||||||
|
my $reference = $notif->getAttribute('reference');
|
||||||
|
|
||||||
|
# Check if this pending notification has been seen
|
||||||
|
if ( my $refId = $refs->{$reference} ) {
|
||||||
|
|
||||||
|
# Verity that checkboxes have been checked
|
||||||
|
my @toCheck = $notif->getElementsByTagName('check');
|
||||||
|
if ( my $toCheckCount = @toCheck ) {
|
||||||
|
unless ($checks->{$refId}
|
||||||
|
and $toCheckCount == @{ $checks->{$refId} } )
|
||||||
|
{
|
||||||
|
$self->p->userNotice(
|
||||||
|
"$uid has not accepted notification $reference"
|
||||||
|
);
|
||||||
|
$result = $fileResult = 0;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Current pending notification has not been found in
|
||||||
|
# request
|
||||||
|
$result = $fileResult = 0;
|
||||||
|
$self->lmLog(
|
||||||
|
'Current pending notification has not been found',
|
||||||
|
'debug' );
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Register acceptation
|
||||||
|
$self->p->userNotice(
|
||||||
|
"$uid has accepted notification $reference");
|
||||||
|
$self->p->updatePersistentSession( $req,
|
||||||
|
{ "notification_$reference" => time() } );
|
||||||
|
$self->lmLog(
|
||||||
|
"Notification $reference registered in persistent session",
|
||||||
|
'debug'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Notifications accepted for this file, delete it unless it's a wildcard
|
||||||
|
if ( $fileResult and exists $forUser->{$fileName} ) {
|
||||||
|
$self->lmLog( "Notification file deleted", 'debug' );
|
||||||
|
$self->notifObject->delete($fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unless ($result) {
|
||||||
|
|
||||||
|
# One pending notification has been found and not accepted,
|
||||||
|
# restart process to display pending notifications
|
||||||
|
# TODO: is it a good idea to launch all 'afterDatas' subs ?
|
||||||
|
$self->lmLog(
|
||||||
|
'Pending notification has been found and not accepted',
|
||||||
|
'debug' );
|
||||||
|
return $self->p->do( $req, $self->p->afterDatas );
|
||||||
|
}
|
||||||
|
|
||||||
|
# All pending notifications have been accepted, restore cookies and
|
||||||
|
# launch 'controlUrl' to restore "urldc" using do()
|
||||||
|
$self->lmLog( 'All pending notifications have been accepted', 'debug' );
|
||||||
|
$self->rebuildCookies($req);
|
||||||
|
return $self->p->do( $req, ['controlUrl'] );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# No notifications checked here, this entry point must not be called.
|
||||||
|
# Redirecting to portal
|
||||||
|
$self->lmLog( 'No notifications checked', 'debug' );
|
||||||
|
$req->mustRedirect(1);
|
||||||
|
return $self->p->do( $req, [] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*rebuildCookies =
|
||||||
|
\&Lemonldap::NG::Portal::Plugins::Notifications::rebuildCookies;
|
||||||
|
|
||||||
|
1;
|
|
@ -13,44 +13,12 @@ package Lemonldap::NG::Portal::Plugins::Notifications;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
use XML::LibXSLT;
|
|
||||||
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_NOTIFICATION);
|
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_NOTIFICATION);
|
||||||
|
|
||||||
our $VERSION = '2.0.0';
|
our $VERSION = '2.0.0';
|
||||||
|
|
||||||
# Lemonldap::NG::Portal::Main::Plugin provides addAuthRoute() and
|
|
||||||
# addUnauthRoute() methods in addition of Lemonldap::NG::Common::Module.
|
|
||||||
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
||||||
|
|
||||||
# PROPERTIES
|
|
||||||
|
|
||||||
sub parser {
|
|
||||||
return $_[0]->notifObject->parser;
|
|
||||||
}
|
|
||||||
|
|
||||||
# XSLT document
|
|
||||||
has stylesheet => (
|
|
||||||
is => 'rw',
|
|
||||||
lazy => 1,
|
|
||||||
builder => sub {
|
|
||||||
my $self = $_[0];
|
|
||||||
my $xslt = XML::LibXSLT->new();
|
|
||||||
my $styleFile = (
|
|
||||||
(
|
|
||||||
$self->conf->{notificationXSLTfile}
|
|
||||||
and -e $self->conf->{notificationXSLTfile}
|
|
||||||
)
|
|
||||||
? $self->conf->{notificationXSLTfile}
|
|
||||||
: $self->conf->{templatesDir} . '/common/notification.xsl'
|
|
||||||
);
|
|
||||||
die "$styleFile not found" unless ( -e $styleFile );
|
|
||||||
return $xslt->parse_stylesheet( $self->parser->parse_file($styleFile) );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
# Underlying notifications storage object (File, DBI, LDAP,...)
|
|
||||||
has notifObject => ( is => 'rw' );
|
|
||||||
|
|
||||||
# INTERFACE
|
# INTERFACE
|
||||||
|
|
||||||
# Declare additional process steps
|
# Declare additional process steps
|
||||||
|
@ -59,6 +27,10 @@ sub afterDatas { 'checkNotifDuringAuth' }
|
||||||
# For now, notifications are done only during authentication process
|
# For now, notifications are done only during authentication process
|
||||||
#sub forAuthUser { 'checkNotifForAuthUser' }
|
#sub forAuthUser { 'checkNotifForAuthUser' }
|
||||||
|
|
||||||
|
# PROPERTIES
|
||||||
|
|
||||||
|
has module => ( is => 'rw' );
|
||||||
|
|
||||||
# INITIALIZATION
|
# INITIALIZATION
|
||||||
|
|
||||||
sub init {
|
sub init {
|
||||||
|
@ -83,6 +55,7 @@ sub init {
|
||||||
"Unable to load Lemonldap::NG::Common::Notifications::$type: $@");
|
"Unable to load Lemonldap::NG::Common::Notifications::$type: $@");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
$type->import( $self->conf->{oldNotifFormat} ? 'XML' : 'JSON' );
|
||||||
|
|
||||||
# TODO: use conf database?
|
# TODO: use conf database?
|
||||||
|
|
||||||
|
@ -91,7 +64,16 @@ sub init {
|
||||||
p => $self->p,
|
p => $self->p,
|
||||||
conf => $self->p->conf
|
conf => $self->p->conf
|
||||||
};
|
};
|
||||||
unless ( eval { $self->notifObject( $type->new($prms) ); } ) {
|
|
||||||
|
if ( $self->conf->{oldNotifFormat} ) {
|
||||||
|
$self->module( $self->p->loadModule('::Lib::Notifications::XML') )
|
||||||
|
or return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->module( $self->p->loadModule('::Lib::Notifications::JSON') )
|
||||||
|
or return 0;
|
||||||
|
}
|
||||||
|
unless ( eval { $self->module->notifObject( $type->new($prms) ); } ) {
|
||||||
$self->error($@);
|
$self->error($@);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -114,7 +96,9 @@ sub init {
|
||||||
|
|
||||||
sub checkNotifDuringAuth {
|
sub checkNotifDuringAuth {
|
||||||
my ( $self, $req ) = @_;
|
my ( $self, $req ) = @_;
|
||||||
if ( $req->{datas}->{notification} = $self->checkForNotifications($req) ) {
|
if ( $req->{datas}->{notification} =
|
||||||
|
$self->module->checkForNotifications($req) )
|
||||||
|
{
|
||||||
$self->rebuildCookies($req);
|
$self->rebuildCookies($req);
|
||||||
|
|
||||||
# Restore and cipher cookies
|
# Restore and cipher cookies
|
||||||
|
@ -125,208 +109,9 @@ sub checkNotifDuringAuth {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Search for notifications and if any, returns HTML fragment.
|
|
||||||
# TODO: replace this by JSON+Ajax
|
|
||||||
sub checkForNotifications {
|
|
||||||
my ( $self, $req ) = @_;
|
|
||||||
|
|
||||||
# Look for pending notifications in database
|
|
||||||
my $uid = $req->sessionInfo->{ $self->notifObject->notifField };
|
|
||||||
my ( $notifs, $forUser ) = $self->notifObject->getNotifications($uid);
|
|
||||||
my $form;
|
|
||||||
return 0 unless ($notifs);
|
|
||||||
|
|
||||||
# Transform notifications
|
|
||||||
my $i = 0; #Files count
|
|
||||||
foreach my $file ( values %$notifs ) {
|
|
||||||
eval {
|
|
||||||
my $xml = $self->parser->parse_string($file);
|
|
||||||
my $j = 0; #Notifications count
|
|
||||||
foreach my $notif (
|
|
||||||
$xml->documentElement->getElementsByTagName('notification') )
|
|
||||||
{
|
|
||||||
|
|
||||||
# Get the reference
|
|
||||||
my $reference = $notif->getAttribute('reference');
|
|
||||||
|
|
||||||
$self->lmLog( "Get reference $reference", 'debug' );
|
|
||||||
|
|
||||||
# Check it in session
|
|
||||||
if ( exists $req->{sessionInfo}->{"notification_$reference"} ) {
|
|
||||||
|
|
||||||
# The notification was already accepted
|
|
||||||
$self->lmLog(
|
|
||||||
"Notification $reference was already accepted",
|
|
||||||
'debug' );
|
|
||||||
|
|
||||||
# Remove it from XML
|
|
||||||
$notif->unbindNode();
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check condition if any
|
|
||||||
my $condition = $notif->getAttribute('condition');
|
|
||||||
|
|
||||||
if ($condition) {
|
|
||||||
|
|
||||||
$self->lmLog( "Get condition $condition", 'debug' );
|
|
||||||
|
|
||||||
unless ( $self->p->HANDLER->safe->reval($condition) ) {
|
|
||||||
$self->lmLog( "Notification condition not accepted",
|
|
||||||
'debug' );
|
|
||||||
|
|
||||||
# Remove it from XML
|
|
||||||
$notif->unbindNode();
|
|
||||||
next;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$j++;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Go to next file if no notification found
|
|
||||||
next unless $j;
|
|
||||||
$i++;
|
|
||||||
|
|
||||||
# Transform XML into HTML
|
|
||||||
my $results = $self->stylesheet->transform( $xml, start => $i );
|
|
||||||
$form .= $self->stylesheet->output_string($results);
|
|
||||||
};
|
|
||||||
if ($@) {
|
|
||||||
$self->lmLog(
|
|
||||||
"Bad XML file: a notification for $uid was not done ($@)",
|
|
||||||
'warn' );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Stop here if nothing to display
|
|
||||||
return 0 unless $i;
|
|
||||||
|
|
||||||
# Returns HTML fragment
|
|
||||||
$req->id( $self->p->HANDLER->tsv->{cipher}->encrypt( $req->id ) );
|
|
||||||
return $form;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub getNotifBack {
|
sub getNotifBack {
|
||||||
my ( $self, $req, $name ) = @_;
|
my $self = shift;
|
||||||
|
return $self->module->getNotifBack(@_);
|
||||||
# Look if all notifications have been accepted. If not, redirects to
|
|
||||||
# portal
|
|
||||||
|
|
||||||
# Search for Lemonldap::NG cookie (ciphered)
|
|
||||||
my $id;
|
|
||||||
unless ( $id = $req->cookies->{ $self->{conf}->{cookieName} } ) {
|
|
||||||
return $self->p->sendError( $req, 'No cookie found', 401 );
|
|
||||||
}
|
|
||||||
$id = $self->p->HANDLER->tsv->{cipher}->decrypt($id)
|
|
||||||
or return $self->sendError( $req, 'Unable to decrypt', 500 );
|
|
||||||
|
|
||||||
# Verify that session exists
|
|
||||||
$req->userData( $self->p->HANDLER->retrieveSession($id) )
|
|
||||||
or return $self->sendError( $req, 'Unknown session', 401 );
|
|
||||||
|
|
||||||
# Restore datas
|
|
||||||
$self->p->importHandlerDatas($req);
|
|
||||||
my $uid = $req->sessionInfo->{ $self->notifObject->notifField };
|
|
||||||
|
|
||||||
my ( $notifs, $forUser ) = $self->notifObject->getNotifications($uid);
|
|
||||||
if ($notifs) {
|
|
||||||
|
|
||||||
# Get accepted notifications
|
|
||||||
my ( $refs, $checks ) = ( {}, {} );
|
|
||||||
my $prms = $req->parameters;
|
|
||||||
foreach ( keys %$prms ) {
|
|
||||||
my $v = $prms->{$_};
|
|
||||||
if (s/^reference//) {
|
|
||||||
$refs->{$v} = $_;
|
|
||||||
}
|
|
||||||
elsif ( s/^check// and /^(\d+x\d+)x(\d+)$/ and $v eq 'accepted' ) {
|
|
||||||
push @{ $checks->{$1} }, $2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
my $result = 1;
|
|
||||||
foreach my $fileName ( keys %$notifs ) {
|
|
||||||
my $file = $notifs->{$fileName};
|
|
||||||
my $fileResult = 1;
|
|
||||||
my $xml = $self->parser->parse_string($file);
|
|
||||||
|
|
||||||
# Get pending notifications and verify that they have been accepted
|
|
||||||
foreach my $notif (
|
|
||||||
$xml->documentElement->getElementsByTagName('notification') )
|
|
||||||
{
|
|
||||||
my $reference = $notif->getAttribute('reference');
|
|
||||||
|
|
||||||
# Check if this pending notification has been seen
|
|
||||||
if ( my $refId = $refs->{$reference} ) {
|
|
||||||
|
|
||||||
# Verity that checkboxes have been checked
|
|
||||||
my @toCheck = $notif->getElementsByTagName('check');
|
|
||||||
if ( my $toCheckCount = @toCheck ) {
|
|
||||||
unless ($checks->{$refId}
|
|
||||||
and $toCheckCount == @{ $checks->{$refId} } )
|
|
||||||
{
|
|
||||||
$self->p->userNotice(
|
|
||||||
"$uid has not accepted notification $reference"
|
|
||||||
);
|
|
||||||
$result = $fileResult = 0;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
# Current pending notification has not been found in
|
|
||||||
# request
|
|
||||||
$result = $fileResult = 0;
|
|
||||||
$self->lmLog(
|
|
||||||
'Current pending notification has not been found',
|
|
||||||
'debug' );
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Register acceptation
|
|
||||||
$self->p->userNotice(
|
|
||||||
"$uid has accepted notification $reference");
|
|
||||||
$self->p->updatePersistentSession( $req,
|
|
||||||
{ "notification_$reference" => time() } );
|
|
||||||
$self->lmLog(
|
|
||||||
"Notification $reference registered in persistent session",
|
|
||||||
'debug'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Notifications accepted for this file, delete it unless it's a wildcard
|
|
||||||
if ( $fileResult and exists $forUser->{$fileName} ) {
|
|
||||||
$self->lmLog( "Notification file deleted", 'debug' );
|
|
||||||
$self->notifObject->delete($fileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unless ($result) {
|
|
||||||
|
|
||||||
# One pending notification has been found and not accepted,
|
|
||||||
# restart process to display pending notifications
|
|
||||||
# TODO: is it a good idea to launch all 'afterDatas' subs ?
|
|
||||||
$self->lmLog(
|
|
||||||
'Pending notification has been found and not accepted',
|
|
||||||
'debug' );
|
|
||||||
return $self->p->do( $req, $self->p->afterDatas );
|
|
||||||
}
|
|
||||||
|
|
||||||
# All pending notifications have been accepted, restore cookies and
|
|
||||||
# launch 'controlUrl' to restore "urldc" using do()
|
|
||||||
$self->lmLog( 'All pending notifications have been accepted', 'debug' );
|
|
||||||
$self->rebuildCookies($req);
|
|
||||||
$self->p->do( $req, ['controlUrl'] );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
# No notifications checked here, this entry point must not be called.
|
|
||||||
# Redirecting to portal
|
|
||||||
$self->lmLog( 'No notifications checked', 'debug' );
|
|
||||||
$req->mustRedirect(1);
|
|
||||||
$self->p->do( $req, [] );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rebuildCookies {
|
sub rebuildCookies {
|
||||||
|
|
|
@ -39,6 +39,7 @@ qq{INSERT INTO notifications VALUES ('dwho','testref','2016-05-30 00:00:00','<?x
|
||||||
notificationStorageOptions => {
|
notificationStorageOptions => {
|
||||||
dbiChain => "dbi:SQLite:dbname=$file",
|
dbiChain => "dbi:SQLite:dbname=$file",
|
||||||
},
|
},
|
||||||
|
oldNotifFormat => 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -28,6 +28,7 @@ my $client = LLNG::Manager::Test->new(
|
||||||
notificationStorageOptions => {
|
notificationStorageOptions => {
|
||||||
dirName => 't'
|
dirName => 't'
|
||||||
},
|
},
|
||||||
|
oldNotifFormat => 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
Loading…
Reference in New Issue
Block a user