Lemonldap::NG::Portal::_CAS - Common CAS functions


Lemonldap-NG-Portal documentation Contained in the Lemonldap-NG-Portal distribution.

Index


Code Index:

NAME

Top

Lemonldap::NG::Portal::_CAS - Common CAS functions

SYNOPSIS

Top

use Lemonldap::NG::Portal::_CAS;

DESCRIPTION

Top

This module contains common methods for CAS

METHODS

Top

getCasSession

Try to recover the CAS session corresponding to id and return session datas If id is set to undef, return a new session

returnCasValidateError

Return an error for CAS VALIDATE request

returnCasValidateSuccess

Return success for CAS VALIDATE request

deleteCasSecondarySessions

Find and delete CAS sessions bounded to a primary session

returnCasServiceValidateError

Return an error for CAS SERVICE VALIDATE request

returnCasServiceValidateSuccess

Return success for CAS SERVICE VALIDATE request

returnCasProxyError

Return an error for CAS PROXY request

returnCasProxySuccess

Return success for CAS PROXY request

deleteCasSession

Delete an opened CAS session

callPgtUrl

Call proxy granting URL on CAS client

SEE ALSO

Top

Lemonldap::NG::Portal::IssuerDBCAS

AUTHOR

Top

Clement Oudot, <coudot@linagora.com>

COPYRIGHT AND LICENSE

Top


Lemonldap-NG-Portal documentation Contained in the Lemonldap-NG-Portal distribution.

## @file
# Common CAS functions

## @class
# Common CAS functions
package Lemonldap::NG::Portal::_CAS;

use strict;
use LWP::UserAgent;

our $VERSION = '1.0.0';

## @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
# @return session datas
sub getCasSession {
    my ( $self, $id ) = splice @_;
    my %h;

    # Trying to recover session from CAS session storage
    eval { tie %h, $self->{casStorage}, $id, $self->{casStorageOptions}; };
    if ( $@ or not tied(%h) ) {

        # Session not available
        if ($id) {
            $self->lmLog( "CAS session $id isn't yet available", 'info' );
        }
        else {
            $self->lmLog( "Unable to create new CAS session: $@", 'error' );
        }
        return 0;
    }

    return \%h;
}

## @method void returnCasValidateError()
# Return an error for CAS VALIDATE request
# @return nothing
sub returnCasValidateError {
    my ($self) = splice @_;

    $self->lmLog( "Return CAS validate error", 'debug' );

    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 {
    my ( $self, $username ) = splice @_;

    $self->lmLog( "Return CAS validate success with username $username",
        'debug' );

    print $self->header();
    print "yes\n$username\n";

    $self->quit();
}

## @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 {
    my ( $self, $code, $text ) = splice @_;

    $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();
}

## @method void returnCasServiceValidateSuccess(string username, string pgtIou, string proxies)
# Return success for CAS SERVICE VALIDATE request
# @param username User name
# @param pgtIou Proxy granting ticket IOU
# @param proxies List of used CAS proxies
# @return nothing
sub returnCasServiceValidateSuccess {
    my ( $self, $username, $pgtIou, $proxies ) = splice @_;

    $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";
    if ( defined $pgtIou ) {
        $self->lmLog( "Add proxy granting ticket $pgtIou in response",
            'debug' );
        print
          "\t\t<cas:proxyGrantingTicket>$pgtIou</cas:proxyGrantingTicket>\n";
    }
    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";
    }
    print "\t</cas:authenticationSuccess>\n";
    print "</cas:serviceResponse>\n";

    $self->quit();
}

## @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 {
    my ( $self, $code, $text ) = splice @_;

    $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 {
    my ( $self, $ticket ) = splice @_;

    $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();
}
## @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 {
    my ( $self, $session_id ) = splice @_;
    my $result = 1;

    # Find CAS sessions
    my $cas_sessions =
      $self->{casStorage}
      ->searchOn( $self->{casStorageOptions}, "_cas_id", $session_id );

    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' );

            my $casSessionInfo = $self->getCasSession($cas_session);

            # Delete session
            $result = $self->deleteCasSession($casSessionInfo);
        }
    }
    else {
        $self->lmLog( "No CAS session found for session $session_id ",
            'debug' );
    }

    return $result;

}

## @method boolean deleteCasSession(hashref session)
# Delete an opened CAS session
# @param session Tied session object
# @return result
sub deleteCasSession {
    my ( $self, $session ) = splice @_;

    # Check session object
    unless ( ref($session) eq 'HASH' ) {
        $self->lmLog( "Provided session is not a HASH reference", 'error' );
        return 0;
    }

    # Get session_id
    my $session_id = $session->{_session_id};

    # Delete session
    eval { tied(%$session)->delete() };

    if ($@) {
        $self->lmLog( "Unable to delete CAS session $session_id: $@", 'error' );
        return 0;
    }

    $self->lmLog( "CAS session $session_id deleted", 'debug' );

    return 1;
}

## @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 {
    my ( $self, $pgtUrl, $pgtIou, $pgtId ) = splice @_;

    # LWP User Agent
    my $ua = new LWP::UserAgent;
    push @{ $ua->requests_redirectable }, 'POST';
    $ua->env_proxy();

    # Build URL
    my $url = $pgtUrl;
    $url .= ( $pgtUrl =~ /\?/ ? '&' : '?' );
    $url .= "pgtIou=$pgtIou&pgtId=$pgtId";

    $self->lmLog( "Call URL $url", 'debug' );

    # GET URL
    my $response = $ua->get($url);

    # Return result
    return $response->is_success();

}

1;

__END__