cas_test.module in CAS 6.3
Same filename and directory in other branches
Dummy module implementing a CAS Server.
File
tests/cas_test.moduleView source
<?php
/**
* @file
* Dummy module implementing a CAS Server.
*/
/**
*
*/
function cas_test_cas_phpcas_alter() {
// Set the User-Agent field which is used by SimpleTest to identify testing
// requests.
if (preg_match('/simpletest\\d+/', $GLOBALS['db_prefix'], $matches)) {
phpCAS::setExtraCurlOption(CURLOPT_USERAGENT, drupal_generate_test_ua($matches[0]));
}
// Set all CAS server URLs manually, as this is the only way to specify an
// HTTP (i.e., not HTTPS) connection.
$service_url = phpCAS::getServiceURL();
phpCAS::setServerLoginURL(url('cas_test/login', array(
'query' => array(
'service' => $service_url,
),
'absolute' => TRUE,
)));
switch (variable_get('cas_version', '2.0')) {
case CAS_VERSION_1_0:
phpCAS::setServerServiceValidateURL(url('cas_test/validate', array(
'absolute' => TRUE,
)));
break;
case CAS_VERSION_2_0:
phpCAS::setServerServiceValidateURL(url('cas_test/serviceValidate', array(
'absolute' => TRUE,
)));
phpCAS::setServerProxyValidateURL(url('cas_test/proxyValidate', array(
'absolute' => TRUE,
)));
break;
default:
throw new Exception('Unknown CAS server version.');
break;
}
phpCAS::setServerLogoutURL(url('cas_test/logout', array(
'absolute' => TRUE,
)));
// SAML not currently implemented.
// phpCAS::setServerSamlValidateURL(url('cas_test/samlValidate', array('absolute' => TRUE)));
}
/**
* Implements hook_menu().
*/
function cas_test_menu() {
$items = array();
$items['cas_test/login'] = array(
'page callback' => 'cas_test_login',
'title' => 'CAS Login',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['cas_test/validate'] = array(
'page callback' => 'cas_test_validate',
'title' => 'CAS Validate',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['cas_test/serviceValidate'] = array(
'page callback' => 'cas_test_service_validate',
'title' => 'CAS Service Validate',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['cas_test/proxyValidate'] = array(
'page callback' => 'cas_test_service_validate',
'title' => 'CAS Proxy Ticket Validate',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['cas_test/logout'] = array(
'page callback' => 'cas_test_logout',
'title' => 'CAS Logout',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['cas_test/token'] = array(
'page callback' => 'cas_test_token_evaluate',
'title' => 'CAS Token Test',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Initiate a login request.
*
* Set the 'cas_test_cas_user' variable to an associative array containing:
* - 'name': CAS username.
* - 'attributes': (optional) Any other name-value pairs to be returned by the
* CAS server.
*/
function cas_test_login() {
// Get the service and make a ticket.
$service = $_REQUEST['service'];
$cas_user = variable_get('cas_test_cas_user', '');
if ($cas_user) {
if (!is_array($cas_user)) {
$cas_user = array(
'name' => $cas_user,
'attributes' => array(),
);
}
// Generate a ticket and redirect to the service URL with the login ticket.
$ticket = _cas_test_ticket_generate($service, $cas_user);
// Force redirection.
unset($_REQUEST['destination']);
drupal_goto($service, array(
'ticket' => $ticket,
));
}
elseif (isset($_GET['gateway']) && $_GET['gateway'] == 'true') {
// We were not able to log in the user, so redirect to the service URL.
// Force redirection.
unset($_REQUEST['destination']);
drupal_goto($service);
}
else {
// No CAS name was provided, print an error message.
print "Warning: No CAS name provided.\n";
exit;
}
}
/**
* Validate a ticket using the CAS 1.x protocol.
*/
function cas_test_validate() {
// Prevent this page from being cached.
global $conf;
$conf['cache'] = FALSE;
// Set content type.
drupal_set_header('Content-Type: text/plain; charset=utf-8');
//Obtain the ticket from the url and validate it.
$ticket = $_GET['ticket'];
$service = $_GET['service'];
$cas_user = _cas_test_ticket_validate($service, $ticket);
if ($cas_user) {
$cas_name = $cas_user['name'];
print "yes\n";
print "{$cas_name}\n";
}
else {
print "no\n";
print "\n";
}
exit;
}
/**
* Validate a ticket using the CAS 2.0 protocol.
*/
function cas_test_service_validate() {
// Prevent this page from being cached.
global $conf;
$conf['cache'] = FALSE;
// Set content type.
drupal_set_header('Content-Type: text/xml; charset=utf-8');
$ticket = $_GET['ticket'];
$service = $_GET['service'];
if ($cas_user = _cas_test_ticket_validate($service, $ticket)) {
print theme('cas_service_validate_success', $cas_user['name'], $cas_user['attributes']);
}
else {
$error_code = !$ticket || !$service ? 'INVALID_REQUEST' : 'INVALID_TICKET';
print theme('cas_service_validate_failure', $ticket, $error_code);
}
exit;
}
/**
* Log out a user.
*/
function cas_test_logout() {
if (isset($_GET['url'])) {
print t('Logged out. Continue to @url.', array(
'@url' => $_GET['url'],
));
}
else {
print t('Logged out. No redirection provided.');
}
exit;
}
/**
* Generate a login ticket.
*
* @param $service
* The service URL.
* @param $cas_user
* An associative array containing the following keys:
* - 'name': The CAS username.
* - 'attributes': Any other key-value pairs the CAS server should return.
*
* @return
* A login ticket which may be used to authenticate the CAS username at the
* service URL.
*/
function _cas_test_ticket_generate($service, $cas_user) {
// Generate a one-time ticket.
$ticket = 'ST-' . user_password(32);
// Save the ticket in the database.
$tickets = variable_get('cas_test_tickets', array());
$tickets[$service][$ticket] = $cas_user;
variable_set('cas_test_tickets', $tickets);
// Save the name in the database for single sign-out.
$sso = variable_get('cas_test_sso', array());
$sso[$cas_user['name']][$service][] = $ticket;
variable_set('cas_test_sso', $sso);
return $ticket;
}
/**
* Validate a one-time-use login ticket.
*
* @param $service
* The service URL.
* @param $ticket
* The login or proxy ticket.
*
* @return
* The CAS username corresponding to the ticket, or FALSE if the ticket is
* invalid.
*/
function _cas_test_ticket_validate($service, $ticket) {
// Look up the ticket
$cas_name = FALSE;
$tickets = variable_get('cas_test_tickets', array());
if (isset($tickets[$service][$ticket])) {
$cas_name = $tickets[$service][$ticket];
unset($tickets[$service][$ticket]);
}
return $cas_name;
}
/**
* Sign out the specified CAS user.
*
* @param $cas_user
*/
function cas_test_single_sign_out($cas_name, $double_encode = FALSE) {
$sso = variable_get('cas_test_sso', array());
foreach ($sso[$cas_name] as $service => $tickets) {
foreach ($tickets as $ticket) {
// Generate posting:
$data = array(
'logoutRequest' => t("<samlp:LogoutRequest ID=\"!id\" Version=\"2.0\" IssueInstant=\"!time\">\n<saml:NameID>@NOT_USED@</saml:NameID>\n<samlp:SessionIndex>!ticket</samlp:SessionIndex>\n</samlp:LogoutRequest>", array(
'!id' => user_password(10),
'!time' => time(),
'!ticket' => $ticket,
)),
);
if ($double_encode) {
// Certain CAS servers urlencode the logoutRequest.
$data['logoutRequest'] = urlencode($data['logoutRequest']);
}
// Sign out the user.
$headers = array(
'Content-Type' => 'application/x-www-form-urlencoded',
);
drupal_http_request($service, $headers, 'POST', http_build_query($data, '', '&'));
}
}
unset($sso[$cas_name]);
variable_set('cas_test_sso', $sso);
}
/**
* Evaluate the specified token.
*/
function cas_test_token_evaluate() {
print token_replace_multiple($_GET['token'], array(
'cas' => $_GET['name'],
));
exit(0);
}
Functions
Name | Description |
---|---|
cas_test_cas_phpcas_alter | |
cas_test_login | Initiate a login request. |
cas_test_logout | Log out a user. |
cas_test_menu | Implements hook_menu(). |
cas_test_service_validate | Validate a ticket using the CAS 2.0 protocol. |
cas_test_single_sign_out | Sign out the specified CAS user. |
cas_test_token_evaluate | Evaluate the specified token. |
cas_test_validate | Validate a ticket using the CAS 1.x protocol. |
_cas_test_ticket_generate | Generate a login ticket. |
_cas_test_ticket_validate | Validate a one-time-use login ticket. |