Proper new Lemonldap::NG::Common::Notification
This commit is contained in:
parent
8cff113ce5
commit
d6ab796359
|
@ -1,8 +1,8 @@
|
||||||
##@file
|
##@file
|
||||||
# Notification system for Lemonldap::NG portal and manager
|
# Notification system for Lemonldap::NG
|
||||||
|
|
||||||
##@class
|
##@class
|
||||||
# Notification system for Lemonldap::NG portal and manager
|
# Notification system for Lemonldap::NG
|
||||||
package Lemonldap::NG::Common::Notification;
|
package Lemonldap::NG::Common::Notification;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
|
@ -21,14 +21,14 @@ our ( $msg, $parser );
|
||||||
## @cmethod Lemonldap::NG::Common::Notification new(hashref storage)
|
## @cmethod Lemonldap::NG::Common::Notification new(hashref storage)
|
||||||
# Constructor.
|
# Constructor.
|
||||||
# @param $storage same syntax as Lemonldap::NG::Common::Conf object
|
# @param $storage same syntax as Lemonldap::NG::Common::Conf object
|
||||||
# @return Lemonldap::NG::Common::Notification object
|
# @return Lemonldap::NG::Portal::Notification object
|
||||||
sub new {
|
sub new {
|
||||||
my ( $class, $storage ) = splice @_;
|
my ( $class, $storage ) = splice @_;
|
||||||
my $self = bless {}, $class;
|
my $self = bless {}, $class;
|
||||||
(%$self) = (%$storage);
|
(%$self) = (%$storage);
|
||||||
unless ( $self->{p} ) {
|
unless ( $self->{p} ) {
|
||||||
$msg = "p=>portal is required";
|
$msg = "p=>portal is required";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
my $type = $self->{type};
|
my $type = $self->{type};
|
||||||
$self->{type} = "Lemonldap::NG::Common::Notification::$self->{type}"
|
$self->{type} = "Lemonldap::NG::Common::Notification::$self->{type}"
|
||||||
|
@ -36,9 +36,9 @@ sub new {
|
||||||
eval "require $self->{type}";
|
eval "require $self->{type}";
|
||||||
if ($@) {
|
if ($@) {
|
||||||
$msg = "Error: unknown storage type $type";
|
$msg = "Error: unknown storage type $type";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
unless ($self->_prereq ) {
|
unless ( $self->_prereq ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ sub new {
|
||||||
# @param $level Level (debug|info|notice|error)
|
# @param $level Level (debug|info|notice|error)
|
||||||
sub lmLog {
|
sub lmLog {
|
||||||
my ( $self, $mess, $level ) = splice @_;
|
my ( $self, $mess, $level ) = splice @_;
|
||||||
$self->{p}->lmLog( "[Notification] $mess", $level);
|
$self->{p}->lmLog( "[Notification] $mess", $level );
|
||||||
}
|
}
|
||||||
|
|
||||||
## @method string getNotification(Lemonldap::NG::Portal portal)
|
## @method string getNotification(Lemonldap::NG::Portal portal)
|
||||||
|
@ -64,7 +64,7 @@ sub lmLog {
|
||||||
# @return HTML fragment containing form content
|
# @return HTML fragment containing form content
|
||||||
sub getNotification {
|
sub getNotification {
|
||||||
my ( $self, $portal ) = splice @_;
|
my ( $self, $portal ) = splice @_;
|
||||||
my (@files, $form );
|
my ( @files, $form );
|
||||||
|
|
||||||
# Get user datas,
|
# Get user datas,
|
||||||
my $uid = $portal->{notificationField} || $portal->{whatToTrace} || 'uid';
|
my $uid = $portal->{notificationField} || $portal->{whatToTrace} || 'uid';
|
||||||
|
@ -90,82 +90,81 @@ sub getNotification {
|
||||||
my $xslt = XML::LibXSLT->new();
|
my $xslt = XML::LibXSLT->new();
|
||||||
my $style_file = (
|
my $style_file = (
|
||||||
-e $portal->{notificationXSLTfile}
|
-e $portal->{notificationXSLTfile}
|
||||||
? $portal->{notificationXSLTfile}
|
? $portal->{notificationXSLTfile}
|
||||||
: $portal->getApacheHtdocsPath() . "skins/common/notification.xsl"
|
: $portal->getApacheHtdocsPath() . "skins/common/notification.xsl"
|
||||||
);
|
);
|
||||||
my $style_doc = $parser->parse_file($style_file);
|
my $style_doc = $parser->parse_file($style_file);
|
||||||
my $stylesheet = $xslt->parse_stylesheet($style_doc);
|
my $stylesheet = $xslt->parse_stylesheet($style_doc);
|
||||||
|
|
||||||
# Prepare HTML code
|
# Prepare HTML code
|
||||||
@files = map { $n->{$_} } sort keys %$n;
|
@files = map { $n->{$_} } sort keys %$n;
|
||||||
my $i = 0;
|
my $i = 0; # Files count
|
||||||
foreach my $file (@files) {
|
foreach my $file (@files) {
|
||||||
eval {
|
eval {
|
||||||
my $xml = $parser->parse_string($file);
|
my $xml = $parser->parse_string($file);
|
||||||
my $j = 0; # Notifications count
|
my $j = 0; # Notifications count
|
||||||
|
|
||||||
# Browse notifications in file
|
# Browse notifications in file
|
||||||
foreach my $notif (
|
foreach my $notif (
|
||||||
$xml->documentElement->getElementByTagName('notification')
|
$xml->documentElement->getElementsByTagName('notification') )
|
||||||
)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
# Get the reference
|
|
||||||
my $reference = $notif->getAttribute('reference');
|
|
||||||
|
|
||||||
$self->lmLog( "Get reference $reference", 'debug' );
|
# Get the reference
|
||||||
|
my $reference = $notif->getAttribute('reference');
|
||||||
|
|
||||||
# Check it in session
|
$self->lmLog( "Get reference $reference", 'debug' );
|
||||||
if (
|
|
||||||
exists $portal->{sessionInfo}
|
|
||||||
->{ "notification_" . $reference } )
|
|
||||||
{
|
|
||||||
|
|
||||||
# The notification was already accepted
|
# Check it in session
|
||||||
$self->lmLog(
|
if (
|
||||||
"Notification $reference was already accepted",
|
exists $portal->{sessionInfo}
|
||||||
'debug' );
|
->{ "notification_" . $reference } )
|
||||||
|
{
|
||||||
|
|
||||||
# Remove it from XML
|
# The notification was already accepted
|
||||||
$notif->unbindNode();
|
$self->lmLog(
|
||||||
next;
|
"Notification $reference was already accepted",
|
||||||
|
'debug' );
|
||||||
|
|
||||||
|
# Remove it from XML
|
||||||
|
$notif->unbindNode();
|
||||||
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check condition if any
|
# Check condition if any
|
||||||
my $condition = $notif->getAttribute('condition');
|
my $condition = $notif->getAttribute('condition');
|
||||||
|
|
||||||
if ($condition) {
|
if ($condition) {
|
||||||
|
|
||||||
$self->lmLog( "Get condition $condition", 'debug' );
|
$self->lmLog( "Get condition $condition", 'debug' );
|
||||||
|
|
||||||
unless ( $portal->safe->reval($condition) ) {
|
unless ( $portal->safe->reval($condition) ) {
|
||||||
$self->lmLog( "Notification condition not accepted",
|
$self->lmLog( "Notification condition not accepted",
|
||||||
'debug' );
|
'debug' );
|
||||||
|
|
||||||
# Remove it from XML
|
|
||||||
$notif->unbindNode();
|
|
||||||
next;
|
|
||||||
|
|
||||||
}
|
# Remove it from XML
|
||||||
|
$notif->unbindNode();
|
||||||
|
next;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$j++;
|
$j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Go to next file if no notification found
|
|
||||||
next unless $j;
|
|
||||||
$i++;
|
|
||||||
|
|
||||||
# Transform XML into HTML
|
# Go to next file if no notification found
|
||||||
my $results = $stylesheet->transform( $xml, start => $i );
|
next unless $j;
|
||||||
$form .= $stylesheet->output_string($results);
|
$i++;
|
||||||
};
|
|
||||||
if ($@) {
|
# Transform XML into HTML
|
||||||
$self->lmLog(
|
my $results = $stylesheet->transform( $xml, start => $i );
|
||||||
"Bad XML File: a notification for $uid was not done ($@)",
|
$form .= $stylesheet->output_string($results);
|
||||||
'warn' );
|
};
|
||||||
return 0;
|
if ($@) {
|
||||||
}
|
$self->lmLog(
|
||||||
|
"Bad XML file: a notification for $uid was not done ($@)",
|
||||||
|
'warn' );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Stop here if nothing to display
|
# Stop here if nothing to display
|
||||||
|
@ -175,17 +174,17 @@ sub getNotification {
|
||||||
$i = 0;
|
$i = 0;
|
||||||
while ( my $tmp = shift @{ $portal->{cookie} } ) {
|
while ( my $tmp = shift @{ $portal->{cookie} } ) {
|
||||||
$i++;
|
$i++;
|
||||||
my $t = $portal->{cipher}->encrypt( $tmp->value );
|
my $t = $portal->{cipher}->encrypt( $tmp->value );
|
||||||
unless ( defined($t) ) {
|
unless ( defined($t) ) {
|
||||||
$self->lmLog(
|
$self->lmLog(
|
||||||
"Notification for $uid was not done : $Lemonldap::NG::Common::Crypto::msg",
|
"Notification for $uid was not done : $Lemonldap::NG::Common::Crypto::msg",
|
||||||
'warn'
|
'warn'
|
||||||
);
|
);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
$tmp->value($t);
|
$tmp->value($t);
|
||||||
$form .= qq{<input type="hidden" id="cookie$i" name="cookie$i" value="}
|
$form .= qq{<input type="hidden" id="cookie$i" name="cookie$i" value="}
|
||||||
. $tmp->as_string . '" />';
|
. $tmp->as_string . '" />';
|
||||||
}
|
}
|
||||||
$form .= '<input type="hidden" name="type" value="notification"/>';
|
$form .= '<input type="hidden" name="type" value="notification"/>';
|
||||||
return $form;
|
return $form;
|
||||||
|
@ -199,124 +198,131 @@ sub checkNotification {
|
||||||
my ( $self, $portal ) = splice @_, 0, 2;
|
my ( $self, $portal ) = splice @_, 0, 2;
|
||||||
my ( $refs, $checks );
|
my ( $refs, $checks );
|
||||||
|
|
||||||
# First, rebuild environment (cookies, ...)
|
# First, rebuild environment (cookies,...)
|
||||||
foreach ( $portal->param() ) {
|
foreach ( $portal->param() ) {
|
||||||
if (/^cookie/) {
|
if (/^cookie/) {
|
||||||
my @tmp = split /(?:=|;\s+)/, $portal->param($_);
|
my @tmp = split /(?:=|;\s+)/, $portal->param($_);
|
||||||
my %tmp = @tmp;
|
my %tmp = @tmp;
|
||||||
my $value = $portal->{cipher}->decrypt( $tmp[1] );
|
my $value = $portal->{cipher}->decrypt( $tmp[1] );
|
||||||
unless ( defined($value) ) {
|
unless ( defined($value) ) {
|
||||||
$self->lmLog( "Unable to decrypt cookie", 'warn');
|
$self->lmLog( "Unable to decrypt cookie", 'warn' );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
push @{ $portal->{cookie} },
|
|
||||||
$portal->cookie(
|
|
||||||
-name => $tmp[0],
|
|
||||||
-value => $value,
|
|
||||||
-domain => $tmp{domain},
|
|
||||||
-path => "/",
|
|
||||||
-secure => ( grep( /^secure$/, @tmp ) ? 1 : 0 ),
|
|
||||||
@_,
|
|
||||||
);
|
|
||||||
if ( $tmp[0] eq $portal->{cookieName} ) {
|
|
||||||
my $tmp = $portal->{existingSession};
|
|
||||||
$portal->{existingSession} = sub { 0 };
|
|
||||||
$portal->controlExistingSession($value);
|
|
||||||
$portal->{existingSession} = $tmp;
|
|
||||||
}
|
}
|
||||||
}
|
push @{ $portal->{cookie} },
|
||||||
elsif (s/^reference//) {
|
$portal->cookie(
|
||||||
$refs->{$_} = $portal->param("reference$_");
|
-name => $tmp[0],
|
||||||
}
|
-value => $value,
|
||||||
elsif ( s/^check// and /^(\d+x\d+)x(\d+)$/ ) {
|
-domain => $tmp{domain},
|
||||||
push @{ $checks->{$1} }, $2;
|
-path => "/",
|
||||||
}
|
-secure => ( grep( /^secure$/, @tmp ) ? 1 : 0 ),
|
||||||
|
@_,
|
||||||
|
);
|
||||||
|
if ( $tmp[0] eq $portal->{cookieName} ) {
|
||||||
|
my $tmp = $portal->{existingSession};
|
||||||
|
$portal->{existingSession} = sub { 0 };
|
||||||
|
$portal->controlExistingSession($value);
|
||||||
|
$portal->{existingSession} = $tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif (s/^reference//) {
|
||||||
|
$refs->{$_} = $portal->param("reference$_");
|
||||||
|
}
|
||||||
|
elsif ( s/^check// and /^(\d+x\d+)x(\d+)$/ ) {
|
||||||
|
push @{ $checks->{$1} }, $2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$portal->controlExistingSession() unless ( $portal->{sessionInfo} );
|
$portal->controlExistingSession() unless ( $portal->{sessionInfo} );
|
||||||
unless ( $portal->{sessionInfo} ) {
|
unless ( $portal->{sessionInfo} ) {
|
||||||
$self->lmLog( "Invalid session", 'warn' );
|
$self->lmLog( "Invalid session", 'warn' );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
my $result = 1;
|
my $result = 1;
|
||||||
foreach my $ref ( keys %$refs ) {
|
foreach my $ref ( keys %$refs ) {
|
||||||
my $uid =
|
my $uid =
|
||||||
$portal->{notificationField}
|
$portal->{notificationField}
|
||||||
|| $portal->{whatToTrace}
|
|| $portal->{whatToTrace}
|
||||||
|| 'uid';
|
|| 'uid';
|
||||||
$uid =~ s/\$//g;
|
$uid =~ s/\$//g;
|
||||||
$uid = $portal->{sessionInfo}->{$uid};
|
$uid = $portal->{sessionInfo}->{$uid};
|
||||||
|
|
||||||
# Get notifications by references
|
# Get notifications by references
|
||||||
# 1. For the user
|
# 1. For the user
|
||||||
my $user = $self->_get( $uid, $refs->{$ref} );
|
my $user = $self->_get( $uid, $refs->{$ref} );
|
||||||
|
|
||||||
# 2. For all users
|
# 2. For all users
|
||||||
my $all = $self->_get( $portal->{notificationWildcard}, $refs->{$ref} );
|
my $all = $self->_get( $portal->{notificationWildcard}, $refs->{$ref} );
|
||||||
|
|
||||||
# 3. Join results
|
# 3. Join results
|
||||||
my $files = {};
|
my $files = {};
|
||||||
if ( $user and $all ) { $files = { %$user, %$all }; }
|
if ( $user and $all ) { $files = { %$user, %$all }; }
|
||||||
else { $files = { $user ? $user : $all; }
|
else { $files = $user ? $user : $all; }
|
||||||
|
|
||||||
unless ($files) {
|
unless ($files) {
|
||||||
$self->lmLog( "Can't find notification $refs->{$ref} for $uid",
|
$self->lmLog( "Can't find notification $refs->{$ref} for $uid",
|
||||||
'error');
|
'error' );
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Browse found files
|
# Browse found files
|
||||||
foreach my $files ( keys %$files ) {
|
foreach my $file ( keys %$files ) {
|
||||||
my $xml;
|
my $xml;
|
||||||
eval { $xml = $parser->parse_string( $files->{$file} ) };
|
eval { $xml = $parser->parse_string( $files->{$file} ) };
|
||||||
if ($@) {
|
if ($@) {
|
||||||
$self->lmLog( "Bad XML notifications for $uid", 'error' );
|
$self->lmLog( "Bad XML notification for $uid", 'error' );
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Browse notifications in file
|
|
||||||
foreach my $notif (
|
|
||||||
$xml->documentElement->getElementsByTagName('notification') )
|
|
||||||
{
|
|
||||||
my $reference = $notif->getAttribute('reference');
|
|
||||||
my @tmp = $notif->getElementsByTagName('check');
|
|
||||||
my $checkCount = @tmp;
|
|
||||||
if ( $checkCount == 0
|
|
||||||
or
|
|
||||||
( $checks->{$ref} and $checkCount == @{ $checks->{$ref} } )
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
# Notification is accepted
|
# Browse notifications in file
|
||||||
|
foreach my $notif (
|
||||||
|
$xml->documentElement->getElementsByTagName('notification') )
|
||||||
|
{
|
||||||
|
my $reference = $notif->getAttribute('reference');
|
||||||
|
my @tmp = $notif->getElementsByTagName('check');
|
||||||
|
my $checkCount = @tmp;
|
||||||
|
if ( $checkCount == 0
|
||||||
|
or
|
||||||
|
( $checks->{$ref} and $checkCount == @{ $checks->{$ref} } )
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
$self->lmLog(
|
# Notification is accepted
|
||||||
"$uid has accepted notification $refs->{$ref}",
|
|
||||||
'notice');
|
|
||||||
# 1. Register acceptation in persistent session
|
|
||||||
my $time = time();
|
|
||||||
my $notifkey = "notification_" . $refs->{$ref};
|
|
||||||
$portal->updatePersistentSession(
|
|
||||||
{ $notifkey => $time },
|
|
||||||
);
|
|
||||||
|
|
||||||
$self->lmLog("Notification " . $refs->{$ref}
|
$self->lmLog(
|
||||||
. " registered in persistent session",
|
"$uid has accepted notification $refs->{$ref}",
|
||||||
'debug'
|
'notice' );
|
||||||
);
|
|
||||||
|
|
||||||
|
# 1. Register acceptation in persistent session
|
||||||
# 2. Delete it if not a wildcard notification
|
my $time = time();
|
||||||
if ( exists $user->{$file} ) {
|
my $notifkey = "notification_" . $refs->{$ref};
|
||||||
|
$portal->updatePersistentSession(
|
||||||
if ( $self->_delete($file) ) {
|
{ $notifkey => $time },
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
$self->lmLog(
|
||||||
|
"Notification "
|
||||||
|
. $refs->{$ref}
|
||||||
|
. " registered in persistent session",
|
||||||
|
'debug'
|
||||||
|
);
|
||||||
|
|
||||||
|
# 2. Delete it if not a wildcard notification
|
||||||
|
if ( exists $user->{$file} ) {
|
||||||
|
|
||||||
|
if ( $self->_delete($file) ) {
|
||||||
$self->lmLog(
|
$self->lmLog(
|
||||||
"Notification " . $refs->{$ref} . " deleted",
|
"Notification " . $refs->{$ref} . " deleted",
|
||||||
'debug' );
|
'debug' );
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
$self->lmLog("Unable to delete notification $refs->{$ref} for $uid", 'warn');
|
$self->lmLog(
|
||||||
}
|
"Unable to delete notification $refs->{$ref} for $uid",
|
||||||
}
|
'error'
|
||||||
}
|
);
|
||||||
else {
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
$self->lmLog(
|
$self->lmLog(
|
||||||
"$uid has not accepted notification $refs->{$ref}",
|
"$uid has not accepted notification $refs->{$ref}",
|
||||||
'notice' );
|
'notice' );
|
||||||
|
@ -457,7 +463,6 @@ sub _newNotif {
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
=head1 NAME
|
=head1 NAME
|
||||||
|
@ -468,7 +473,7 @@ Lemonldap::NG::Common::Notification - Provides notification messages system.
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
use Lemonldap::NG::Common;
|
use Lemonldap::NG::Portal;
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
@ -477,7 +482,6 @@ Lemonldap::NG::Common::Notification.
|
||||||
=head1 SEE ALSO
|
=head1 SEE ALSO
|
||||||
|
|
||||||
L<Lemonldap::NG::Portal>,
|
L<Lemonldap::NG::Portal>,
|
||||||
L<Lemonldap::NG::Manager>,
|
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
@ -502,3 +506,5 @@ it under the same terms as Perl itself, either Perl version 5.10.0 or,
|
||||||
at your option, any later version of Perl 5 you may have available.
|
at your option, any later version of Perl 5 you may have available.
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user