lemonldap-ng/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/CDC.pm

204 lines
5.2 KiB
Perl

## @file
# Module for SAML Common Domain Cookie Support
## @class Lemonldap::NG::Portal::CDC
# Class for SAML Common Domain Cookie Support
package Lemonldap::NG::Portal::CDC;
use strict;
use warnings;
use MIME::Base64;
use Lemonldap::NG::Portal::SharedConf; # inherits
use Lemonldap::NG::Portal::_SAML; # inherits
our $VERSION = '1.0.0';
our @ISA = qw(Lemonldap::NG::Portal::_SAML Lemonldap::NG::Portal::SharedConf);
## @method int process()
# Main method to process CDC requests
# @return portal error code
sub process {
my $self = shift;
my $cdc_idp = "";
my $cdc_cookie = "";
# Default values
my $cdc_name = $self->{samlCommonDomainCookieName} || '_saml_idp';
my $cdc_domain = $self->{samlCommonDomainCookieDomain} || $ENV{'HTTP_HOST'};
$self->lmLog( "[CDC] Cookie name: $cdc_name", 'debug' );
$self->lmLog( "[CDC] Domain name: $cdc_domain", 'debug' );
# Request parameter
my $action = $self->param('action') || ""; # What we do
my $idp = $self->param('idp'); # IDP ID in write mode
# Control URL
my $control_url = $self->_sub('controlUrlOrigin');
unless ( $control_url == PE_OK ) {
$self->lmLog( "[CDC] Bad URL", 'error' );
return $control_url;
}
# Get cookie
my %cookies = fetch CGI::Cookie;
$cdc_cookie = $cookies{$cdc_name} if %cookies;
$cdc_cookie &&= $cdc_cookie->value;
if ($cdc_cookie) {
$self->lmLog( "[CDC] Cookie found with value $cdc_cookie", 'debug' );
}
# Write request
# Called in an iFrame
# Get or build common domain cookie
# Append IDP to common domain cookie
if ( $action eq 'write' ) {
$self->lmLog( "[CDC] Write request detected", 'debug' );
# Check IDP value
unless ($idp) {
$self->lmLog( "[CDC] No IDP given", 'error' );
return PE_SAML_ERROR;
}
# Add IDP value
$self->lmLog( "[CDC] Will add IDP $idp to IDP list", 'debug' );
my $encoded_idp = encode_base64( $idp, '' );
# Remove IDP value if already present
$cdc_cookie =~ s/$encoded_idp(\s+)?//g;
# Add a space separator
$cdc_cookie .= ( $cdc_cookie ? " " : "" );
$cdc_cookie .= $encoded_idp;
$self->lmLog( "[CDC] Build cookie $cdc_name with value $cdc_cookie",
'debug' );
# Build cookie
push @{ $self->{cookie} }, $self->cookie(
-name => $cdc_name,
-value => $cdc_cookie,
-domain => $cdc_domain,
-path => "/", # See SAML protocol
-secure => 1, # See SAML protocol
-httponly => $self->{httpOnly},
-expires => $self->{cookieExpiration},
);
}
# Read request
# Get last IDP from domain cookie
# Return on SP with idp as parameter
elsif ( $action eq 'read' ) {
$self->lmLog( "[CDC] Read request detected", 'debug' );
# Get last IDP from cookie
if ($cdc_cookie) {
$cdc_idp = decode_base64( ( split /\s+/, $cdc_cookie )[-1] );
$self->lmLog( "[CDC] Get value $cdc_idp", 'debug' );
}
else {
$self->lmLog( "[CDC] No cookie, set a default value", 'debug' );
$cdc_idp = 'notfound';
}
}
# Redirect if needed
if ( $self->{urldc} ) {
# Add CDC IDP in return URL if needed
# olStyleUrl can be set to 1 to use & instead of ;
$self->{urldc} .= (
$cdc_idp
? (
$self->{urldc} =~ /\?/
? ( $self->{oldStyleUrl} ? '&' : ';' ) . 'idp=' . $cdc_idp
: '?idp=' . $cdc_idp
)
: ''
);
# Redirect
$self->_sub('autoRedirect');
}
if ($cdc_cookie) {
# Parse cookie to display it if not redirected
my @cdc_values =
map( decode_base64($_), ( split( /\s+/, $cdc_cookie ) ) );
$self->{cdc_values} = \@cdc_values;
}
return PE_OK;
}
1;
__END__
=head1 NAME
=encoding utf8
Lemonldap::NG::Portal::CDC - Manage SAML Common Domain Cookie
=head1 SYNOPSIS
use Lemonldap::NG::Portal::CDC;
my $portal = new Lemonldap::NG::Portal::CDC();
$portal->process();
# Write here HTML to manage errors and confirmation messages
=head1 DESCRIPTION
Lemonldap::NG::Portal::CDC - Manage SAML Common Domain Cookie
See L<Lemonldap::NG::Portal::SharedConf> for a complete example of use of
Lemonldap::Portal::* libraries.
=head1 METHODS
=head3 process
Main method.
=head1 SEE ALSO
L<Lemonldap::NG::Handler>, L<Lemonldap::NG::Portal::SharedConf>, L<CGI>,
L<http://lemonldap-ng.org/>
=head1 AUTHOR
Clement Oudot, E<lt>clement@oodo.netE<gt>
=head1 BUG REPORT
Use OW2 system to report bug or ask for features:
L<http://jira.ow2.org>
=head1 DOWNLOAD
Lemonldap::NG is available at
L<http://forge.objectweb.org/project/showfiles.php?group_id=274>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2010 by Clement Oudot, E<lt>clement@oodo.netE<gt>
This library is free software; you can redistribute it and/or modify
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.
=cut