2010-08-25 16:23:45 +02:00
|
|
|
## @file
|
|
|
|
# Common CAS functions
|
|
|
|
|
|
|
|
## @class
|
|
|
|
# Common CAS functions
|
|
|
|
package Lemonldap::NG::Portal::_CAS;
|
|
|
|
|
|
|
|
use strict;
|
2013-10-08 06:35:38 +02:00
|
|
|
use Lemonldap::NG::Portal::_Browser;
|
2014-04-16 17:19:59 +02:00
|
|
|
use Lemonldap::NG::Common::Session;
|
2010-08-25 16:23:45 +02:00
|
|
|
|
2013-10-08 06:35:38 +02:00
|
|
|
our @ISA = (qw(Lemonldap::NG::Portal::_Browser));
|
2016-03-17 23:19:44 +01:00
|
|
|
our $VERSION = '2.0.0';
|
2010-08-25 16:23:45 +02:00
|
|
|
|
|
|
|
## @method hashref getCasSession(string id)
|
|
|
|
# Try to recover the CAS session corresponding to id and return session datas
|
|
|
|
# If id is set to undef, return a new session
|
|
|
|
# @param id session reference
|
2014-04-16 17:19:59 +02:00
|
|
|
# @return CAS session object
|
2010-08-25 16:23:45 +02:00
|
|
|
sub getCasSession {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ( $self, $id ) = @_;
|
2010-08-25 16:23:45 +02:00
|
|
|
|
2014-04-16 17:19:59 +02:00
|
|
|
my $casSession = Lemonldap::NG::Common::Session->new(
|
|
|
|
{
|
|
|
|
storageModule => $self->{casStorage},
|
|
|
|
storageModuleOptions => $self->{casStorageOptions},
|
|
|
|
cacheModule => $self->{localSessionStorage},
|
|
|
|
cacheModuleOptions => $self->{localSessionStorageOptions},
|
|
|
|
id => $id,
|
|
|
|
kind => "CAS",
|
|
|
|
}
|
|
|
|
);
|
2010-08-25 16:23:45 +02:00
|
|
|
|
2014-07-24 17:37:12 +02:00
|
|
|
if ( $casSession->error ) {
|
2010-08-25 16:23:45 +02:00
|
|
|
if ($id) {
|
2013-10-13 14:15:01 +02:00
|
|
|
$self->_sub( 'userInfo', "CAS session $id isn't yet available" );
|
2010-08-25 16:23:45 +02:00
|
|
|
}
|
|
|
|
else {
|
2014-04-16 17:19:59 +02:00
|
|
|
$self->lmLog( "Unable to create new CAS session", 'error' );
|
2014-07-24 17:37:12 +02:00
|
|
|
$self->lmLog( $casSession->error, 'error' );
|
2010-08-25 16:23:45 +02:00
|
|
|
}
|
2014-04-16 17:19:59 +02:00
|
|
|
return undef;
|
2010-08-25 16:23:45 +02:00
|
|
|
}
|
|
|
|
|
2014-04-16 17:19:59 +02:00
|
|
|
return $casSession;
|
2010-08-25 16:23:45 +02:00
|
|
|
}
|
|
|
|
|
2010-08-25 17:33:33 +02:00
|
|
|
## @method void returnCasValidateError()
|
|
|
|
# Return an error for CAS VALIDATE request
|
|
|
|
# @return nothing
|
|
|
|
sub returnCasValidateError {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ($self) = @_;
|
2010-08-25 17:33:33 +02:00
|
|
|
|
2010-08-26 14:24:38 +02:00
|
|
|
$self->lmLog( "Return CAS validate error", 'debug' );
|
|
|
|
|
2010-08-25 17:33:33 +02:00
|
|
|
print $self->header();
|
|
|
|
print "no\n\n";
|
|
|
|
|
|
|
|
$self->quit();
|
|
|
|
}
|
|
|
|
|
|
|
|
## @method void returnCasValidateSuccess(string username)
|
|
|
|
# Return success for CAS VALIDATE request
|
|
|
|
# @param username User name
|
|
|
|
# @return nothing
|
|
|
|
sub returnCasValidateSuccess {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ( $self, $username ) = @_;
|
2010-08-25 17:33:33 +02:00
|
|
|
|
2010-08-26 14:24:38 +02:00
|
|
|
$self->lmLog( "Return CAS validate success with username $username",
|
|
|
|
'debug' );
|
|
|
|
|
2010-08-25 17:33:33 +02:00
|
|
|
print $self->header();
|
|
|
|
print "yes\n$username\n";
|
|
|
|
|
|
|
|
$self->quit();
|
|
|
|
}
|
|
|
|
|
2010-08-26 14:24:38 +02:00
|
|
|
## @method void returnCasServiceValidateError(string code, string text)
|
|
|
|
# Return an error for CAS SERVICE VALIDATE request
|
|
|
|
# @param code CAS error code
|
|
|
|
# @param text Error text
|
|
|
|
# @return nothing
|
|
|
|
sub returnCasServiceValidateError {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ( $self, $code, $text ) = @_;
|
2010-08-26 14:24:38 +02:00
|
|
|
|
|
|
|
$code ||= 'INTERNAL_ERROR';
|
|
|
|
$text ||= 'No description provided';
|
|
|
|
|
|
|
|
$self->lmLog( "Return CAS service validate error $code ($text)", 'debug' );
|
|
|
|
|
|
|
|
print $self->header( -type => 'application/xml' );
|
|
|
|
print "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>\n";
|
|
|
|
print "\t<cas:authenticationFailure code=\"$code\">\n";
|
|
|
|
print "\t\t$text\n";
|
|
|
|
print "\t</cas:authenticationFailure>\n";
|
|
|
|
print "</cas:serviceResponse>\n";
|
|
|
|
|
|
|
|
$self->quit();
|
|
|
|
}
|
|
|
|
|
2015-05-09 19:49:56 +02:00
|
|
|
## @method void returnCasServiceValidateSuccess(string username, string pgtIou, string proxies, hashref attributes)
|
2010-08-26 14:24:38 +02:00
|
|
|
# Return success for CAS SERVICE VALIDATE request
|
|
|
|
# @param username User name
|
2010-08-26 16:43:32 +02:00
|
|
|
# @param pgtIou Proxy granting ticket IOU
|
2010-08-26 18:16:13 +02:00
|
|
|
# @param proxies List of used CAS proxies
|
2015-05-09 19:49:56 +02:00
|
|
|
# @param attributes Attributes to return
|
2010-08-26 14:24:38 +02:00
|
|
|
# @return nothing
|
|
|
|
sub returnCasServiceValidateSuccess {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ( $self, $username, $pgtIou, $proxies, $attributes ) = @_;
|
2010-08-26 14:24:38 +02:00
|
|
|
|
|
|
|
$self->lmLog( "Return CAS service validate success with username $username",
|
|
|
|
'debug' );
|
|
|
|
|
|
|
|
print $self->header( -type => 'application/xml' );
|
|
|
|
print "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>\n";
|
|
|
|
print "\t<cas:authenticationSuccess>\n";
|
|
|
|
print "\t\t<cas:user>$username</cas:user>\n";
|
2015-05-09 19:49:56 +02:00
|
|
|
if ( defined $attributes ) {
|
|
|
|
print "\t\t<cas:attributes>\n";
|
|
|
|
foreach my $attribute ( keys %$attributes ) {
|
|
|
|
foreach my $value (
|
|
|
|
split(
|
|
|
|
$self->{multiValuesSeparator},
|
|
|
|
$attributes->{$attribute}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
print "\t\t\t<cas:$attribute>$value</cas:$attribute>\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
print "\t\t</cas:attributes>\n";
|
|
|
|
}
|
2010-08-26 16:43:32 +02:00
|
|
|
if ( defined $pgtIou ) {
|
|
|
|
$self->lmLog( "Add proxy granting ticket $pgtIou in response",
|
|
|
|
'debug' );
|
|
|
|
print
|
|
|
|
"\t\t<cas:proxyGrantingTicket>$pgtIou</cas:proxyGrantingTicket>\n";
|
|
|
|
}
|
2010-08-26 18:16:13 +02:00
|
|
|
if ($proxies) {
|
|
|
|
$self->lmLog( "Add proxies $proxies in response", 'debug' );
|
|
|
|
print "\t\t<cas:proxies>\n";
|
|
|
|
print "\t\t\t<cas:proxy>$_</cas:proxy>\n"
|
|
|
|
foreach ( split( /$self->{multiValuesSeparator}/, $proxies ) );
|
|
|
|
print "\t\t</cas:proxies>\n";
|
|
|
|
}
|
2010-08-26 14:24:38 +02:00
|
|
|
print "\t</cas:authenticationSuccess>\n";
|
|
|
|
print "</cas:serviceResponse>\n";
|
|
|
|
|
|
|
|
$self->quit();
|
|
|
|
}
|
|
|
|
|
2010-08-26 18:16:13 +02:00
|
|
|
## @method void returnCasProxyError(string code, string text)
|
|
|
|
# Return an error for CAS PROXY request
|
|
|
|
# @param code CAS error code
|
|
|
|
# @param text Error text
|
|
|
|
# @return nothing
|
|
|
|
sub returnCasProxyError {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ( $self, $code, $text ) = @_;
|
2010-08-26 18:16:13 +02:00
|
|
|
|
|
|
|
$code ||= 'INTERNAL_ERROR';
|
|
|
|
$text ||= 'No description provided';
|
|
|
|
|
|
|
|
$self->lmLog( "Return CAS proxy error $code ($text)", 'debug' );
|
|
|
|
|
|
|
|
print $self->header( -type => 'application/xml' );
|
|
|
|
print "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>\n";
|
|
|
|
print "\t<cas:proxyFailure code=\"$code\">\n";
|
|
|
|
print "\t\t$text\n";
|
|
|
|
print "\t</cas:proxyFailure>\n";
|
|
|
|
print "</cas:serviceResponse>\n";
|
|
|
|
|
|
|
|
$self->quit();
|
|
|
|
}
|
|
|
|
|
|
|
|
## @method void returnCasProxySuccess(string ticket)
|
|
|
|
# Return success for CAS PROXY request
|
|
|
|
# @param ticket Proxy ticket
|
|
|
|
# @return nothing
|
|
|
|
sub returnCasProxySuccess {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ( $self, $ticket ) = @_;
|
2010-08-26 18:16:13 +02:00
|
|
|
|
|
|
|
$self->lmLog( "Return CAS proxy success with ticket $ticket", 'debug' );
|
|
|
|
|
|
|
|
print $self->header( -type => 'application/xml' );
|
|
|
|
print "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>\n";
|
|
|
|
print "\t<cas:proxySuccess>\n";
|
|
|
|
print "\t\t<cas:proxyTicket>$ticket</cas:proxyTicket>\n";
|
|
|
|
print "\t</cas:proxySuccess>\n";
|
|
|
|
print "</cas:serviceResponse>\n";
|
|
|
|
|
|
|
|
$self->quit();
|
|
|
|
}
|
2010-08-26 10:42:28 +02:00
|
|
|
## @method boolean deleteCasSecondarySessions(string session_id)
|
|
|
|
# Find and delete CAS sessions bounded to a primary session
|
|
|
|
# @param session_id Primary session ID
|
|
|
|
# @return result
|
|
|
|
sub deleteCasSecondarySessions {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ( $self, $session_id ) = @_;
|
2010-08-26 10:42:28 +02:00
|
|
|
my $result = 1;
|
|
|
|
|
|
|
|
# Find CAS sessions
|
2014-02-26 11:57:49 +01:00
|
|
|
my $moduleOptions = $self->{casStorageOptions} || {};
|
|
|
|
$moduleOptions->{backend} = $self->{casStorage};
|
|
|
|
my $module = "Lemonldap::NG::Common::Apache::Session";
|
|
|
|
|
2010-08-26 10:42:28 +02:00
|
|
|
my $cas_sessions =
|
2014-02-26 11:57:49 +01:00
|
|
|
$module->searchOn( $moduleOptions, "_cas_id", $session_id );
|
2010-08-26 10:42:28 +02:00
|
|
|
|
|
|
|
if ( my @cas_sessions_keys = keys %$cas_sessions ) {
|
|
|
|
|
|
|
|
foreach my $cas_session (@cas_sessions_keys) {
|
|
|
|
|
|
|
|
# Get session
|
|
|
|
$self->lmLog( "Retrieve CAS session $cas_session", 'debug' );
|
|
|
|
|
2014-04-16 17:19:59 +02:00
|
|
|
my $casSession = $self->getCasSession($cas_session);
|
2010-08-26 10:42:28 +02:00
|
|
|
|
|
|
|
# Delete session
|
2014-04-16 17:19:59 +02:00
|
|
|
$result = $self->deleteCasSession($casSession);
|
2010-08-26 10:42:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$self->lmLog( "No CAS session found for session $session_id ",
|
|
|
|
'debug' );
|
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-04-16 17:19:59 +02:00
|
|
|
## @method boolean deleteCasSession(Lemonldap::NG::Common::Session session)
|
2010-08-26 14:24:38 +02:00
|
|
|
# Delete an opened CAS session
|
2014-04-16 17:19:59 +02:00
|
|
|
# @param session object
|
2010-08-26 14:24:38 +02:00
|
|
|
# @return result
|
|
|
|
sub deleteCasSession {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ( $self, $session ) = @_;
|
2010-08-26 14:24:38 +02:00
|
|
|
|
|
|
|
# Check session object
|
2014-04-16 17:19:59 +02:00
|
|
|
unless ( $session && $session->data ) {
|
|
|
|
$self->lmLog( "No session to delete", 'error' );
|
2010-08-26 14:24:38 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Get session_id
|
2014-04-16 17:19:59 +02:00
|
|
|
my $session_id = $session->id;
|
2010-08-26 14:24:38 +02:00
|
|
|
|
|
|
|
# Delete session
|
2014-07-24 17:37:12 +02:00
|
|
|
unless ( $session->remove ) {
|
|
|
|
$self->lmLog( $session->error, 'error' );
|
|
|
|
return 0;
|
|
|
|
}
|
2010-08-26 14:24:38 +02:00
|
|
|
|
|
|
|
$self->lmLog( "CAS session $session_id deleted", 'debug' );
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-08-26 16:43:32 +02:00
|
|
|
## @method boolean callPgtUrl(string pgtUrl, string pgtIou, string pgtId)
|
|
|
|
# Call proxy granting URL on CAS client
|
|
|
|
# @param pgtUrl Proxy granting URL
|
|
|
|
# @param pgtIou Proxy granting ticket IOU
|
|
|
|
# @param pgtId Proxy granting ticket
|
|
|
|
# @return result
|
|
|
|
sub callPgtUrl {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ( $self, $pgtUrl, $pgtIou, $pgtId ) = @_;
|
2010-08-26 16:43:32 +02:00
|
|
|
|
|
|
|
# Build URL
|
|
|
|
my $url = $pgtUrl;
|
|
|
|
$url .= ( $pgtUrl =~ /\?/ ? '&' : '?' );
|
|
|
|
$url .= "pgtIou=$pgtIou&pgtId=$pgtId";
|
|
|
|
|
|
|
|
$self->lmLog( "Call URL $url", 'debug' );
|
|
|
|
|
|
|
|
# GET URL
|
2013-10-08 06:35:38 +02:00
|
|
|
my $response = $self->ua()->get($url);
|
2010-08-26 16:43:32 +02:00
|
|
|
|
|
|
|
# Return result
|
|
|
|
return $response->is_success();
|
|
|
|
}
|
|
|
|
|
2010-08-26 10:42:28 +02:00
|
|
|
1;
|
|
|
|
|
2010-08-25 16:23:45 +02:00
|
|
|
__END__
|
|
|
|
|
|
|
|
=head1 NAME
|
|
|
|
|
|
|
|
=encoding utf8
|
|
|
|
|
|
|
|
Lemonldap::NG::Portal::_CAS - Common CAS functions
|
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
|
|
|
|
use Lemonldap::NG::Portal::_CAS;
|
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
|
|
|
|
This module contains common methods for CAS
|
|
|
|
|
|
|
|
=head1 METHODS
|
|
|
|
|
|
|
|
=head2 getCasSession
|
|
|
|
|
|
|
|
Try to recover the CAS session corresponding to id and return session datas
|
|
|
|
If id is set to undef, return a new session
|
|
|
|
|
2010-08-25 17:33:33 +02:00
|
|
|
=head2 returnCasValidateError
|
|
|
|
|
|
|
|
Return an error for CAS VALIDATE request
|
|
|
|
|
|
|
|
=head2 returnCasValidateSuccess
|
|
|
|
|
|
|
|
Return success for CAS VALIDATE request
|
|
|
|
|
2010-08-26 10:42:28 +02:00
|
|
|
=head2 deleteCasSecondarySessions
|
|
|
|
|
|
|
|
Find and delete CAS sessions bounded to a primary session
|
|
|
|
|
2010-08-26 14:24:38 +02:00
|
|
|
=head2 returnCasServiceValidateError
|
|
|
|
|
|
|
|
Return an error for CAS SERVICE VALIDATE request
|
|
|
|
|
|
|
|
=head2 returnCasServiceValidateSuccess
|
|
|
|
|
|
|
|
Return success for CAS SERVICE VALIDATE request
|
|
|
|
|
2010-08-26 18:16:13 +02:00
|
|
|
=head2 returnCasProxyError
|
|
|
|
|
|
|
|
Return an error for CAS PROXY request
|
|
|
|
|
|
|
|
=head2 returnCasProxySuccess
|
|
|
|
|
|
|
|
Return success for CAS PROXY request
|
|
|
|
|
2010-08-26 14:24:38 +02:00
|
|
|
=head2 deleteCasSession
|
|
|
|
|
|
|
|
Delete an opened CAS session
|
|
|
|
|
2010-08-26 16:43:32 +02:00
|
|
|
=head2 callPgtUrl
|
|
|
|
|
|
|
|
Call proxy granting URL on CAS client
|
|
|
|
|
2010-08-25 16:23:45 +02:00
|
|
|
=head1 SEE ALSO
|
|
|
|
|
2010-08-26 10:42:28 +02:00
|
|
|
L<Lemonldap::NG::Portal::IssuerDBCAS>
|
2010-08-25 16:23:45 +02:00
|
|
|
|
|
|
|
=head1 AUTHOR
|
|
|
|
|
2013-01-31 06:33:10 +01:00
|
|
|
=over
|
|
|
|
|
|
|
|
=item Clement Oudot, E<lt>clem.oudot@gmail.comE<gt>
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
=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>
|
2010-08-25 16:23:45 +02:00
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE
|
|
|
|
|
2013-01-31 06:33:10 +01:00
|
|
|
=over
|
|
|
|
|
2016-01-21 22:15:19 +01:00
|
|
|
=item Copyright (C) 2010-2012 by Clement Oudot, E<lt>clem.oudot@gmail.comE<gt>
|
2013-01-31 06:33:10 +01:00
|
|
|
|
|
|
|
=back
|
2010-08-25 16:23:45 +02:00
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify
|
2013-01-31 06:33:10 +01:00
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see L<http://www.gnu.org/licenses/>.
|
2010-08-25 16:23:45 +02:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|