View source
<?php
define('CAS_LOGIN_COOKIE', 'cas_server_login');
function cas_server_menu() {
$items = array();
$items['cas/login'] = array(
'page callback' => 'cas_server_login',
'title' => 'CAS Login',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['cas/validate'] = array(
'page callback' => 'cas_server_validate',
'title' => 'CAS Validate',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['cas/proxyValidate'] = array(
'page callback' => 'cas_server_service_validate',
'title' => 'CAS Proxy Service Validate',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['cas/serviceValidate'] = array(
'page callback' => 'cas_server_service_validate',
'title' => 'CAS Service Validate',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['cas/logout'] = array(
'page callback' => 'cas_server_logout',
'title' => 'CAS Logout',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
function cas_server_theme() {
return array(
'cas_service_validate_success' => array(
'arguments' => array(
'name' => NULL,
'attributes' => array(),
'style' => 'jasig',
),
'file' => 'cas_server.response.inc',
),
'cas_service_validate_attributes' => array(
'arguments' => array(
'attributes' => array(),
'style' => 'jasig',
),
'file' => 'cas_server.response.inc',
),
'cas_service_validate_failure' => array(
'arguments' => array(
'ticket' => NULL,
'error_code' => NULL,
),
'file' => 'cas_server.response.inc',
),
'cas_service_logout_request' => array(
'arguments' => array(
'ticket' => NULL,
'date' => NULL,
'id' => NULL,
),
'file' => 'cas_server.response.inc',
),
);
}
function cas_server_cas_server_user_attributes($account, $service) {
return array(
'uid' => $account->uid,
'mail' => $account->mail,
'created' => $account->created,
'timezone' => $account->timezone,
'language' => $account->language,
'drupal_roles' => $account->roles,
);
}
function cas_server_service_return() {
global $user;
$service = isset($_COOKIE[CAS_LOGIN_COOKIE]) ? $_COOKIE[CAS_LOGIN_COOKIE] : '';
if ($service && $user->uid) {
$ticket = _cas_server_save_ticket($user->uid, $service);
setcookie(CAS_LOGIN_COOKIE, "", -3600);
drupal_goto($service, 'ticket=' . urlencode($ticket));
}
}
function cas_server_login() {
global $user;
$output = '';
$service = isset($_REQUEST['service']) ? $_REQUEST['service'] : '';
$gateway = isset($_REQUEST['gateway']);
if ($user->uid) {
if ($service) {
$_COOKIE[CAS_LOGIN_COOKIE] = $service;
}
$output = t('You have successfully logged into CAS');
cas_server_service_return();
}
else {
if ($gateway && $service) {
drupal_goto($service);
}
else {
if ($service) {
setcookie(CAS_LOGIN_COOKIE, $service);
}
$output .= l(t('Login'), 'user', array(
'query' => 'destination=cas/login',
));
drupal_goto('user', 'destination=cas/login');
}
}
return $output;
}
function cas_server_validate() {
global $conf;
$conf['cache'] = FALSE;
drupal_set_header('Content-Type: text/plain; charset=utf-8');
$ticket = isset($_REQUEST['ticket']) ? $_REQUEST['ticket'] : '';
$service = isset($_REQUEST['service']) ? $_REQUEST['service'] : '';
$user_name = _cas_server_validate($service, $ticket);
if ($user_name) {
print "yes\n";
print "{$user_name}\n";
}
else {
print "no\n";
print "\n";
}
}
function cas_server_service_validate() {
global $conf;
$conf['cache'] = FALSE;
drupal_set_header('Content-Type: text/xml; charset=utf-8');
$ticket = isset($_REQUEST['ticket']) ? $_REQUEST['ticket'] : '';
$service = isset($_REQUEST['service']) ? $_REQUEST['service'] : '';
$user_name = _cas_server_validate($service, $ticket);
if (!$user_name) {
$cas_error = 'INVALID_TICKET';
}
if (!$ticket || !$service) {
$cas_error = 'INVALID_REQUEST';
}
if ($user_name) {
$account = user_load(array(
'name' => $user_name,
));
$attributes = module_invoke_all('cas_server_user_attributes', $account, $service, $ticket);
$context = array(
'service' => $service,
'ticket' => $ticket,
);
drupal_alter('cas_server_user_attributes', $attributes, $account, $context);
print theme('cas_service_validate_success', $user_name, $attributes);
watchdog('cas', 'User %name CAS sucessully authenticated.', array(
'%name' => $user_name,
));
}
else {
print theme('cas_service_validate_failure', $ticket, $cas_error);
watchdog('cas', 'Ticket %ticket for service %service not recognized.', array(
'%ticket' => $ticket,
'%service' => $service,
));
}
}
function _cas_server_validate($service, $ticket) {
$user_name = '';
$ticket_info = array(
$service,
$ticket,
);
$result = db_query_range("SELECT u.name FROM {cas_server_tickets} t JOIN {users} u ON t.uid=u.uid WHERE t.service = '%s' and t.ticket = '%s' AND valid=1", $ticket_info, 0, 1);
if ($result !== FALSE) {
while ($ticket_data = db_fetch_object($result)) {
$user_name = $ticket_data->name;
}
}
db_query("UPDATE {cas_server_tickets} SET valid=0 WHERE ticket='%s'", array(
$ticket,
));
return $user_name;
}
function _cas_server_save_ticket($uid, $service) {
$time = time();
$ticket = 'ST-' . user_password();
$valid = 1;
$ticket_data = array(
$uid,
$service,
$ticket,
$time,
$valid,
);
if ($uid && $service) {
db_query("INSERT INTO {cas_server_tickets} (uid, service, ticket, timestamp, valid) VALUES (%d, '%s', '%s', %d, %d)", $ticket_data);
}
return $ticket;
}
function cas_server_logout() {
global $user;
watchdog('user', 'Session closed for %name.', array(
'%name' => $user->name,
));
session_destroy();
$null = NULL;
user_module_invoke('logout', $null, $user);
$user = drupal_anonymous_user();
$output = '<p>' . t('You have been logged out successfully.') . '</p>';
if (isset($_REQUEST['url'])) {
$output .= '<p>' . l(t('Continue'), $_REQUEST['url']) . '</p>';
}
return $output;
}
function cas_server_logout_clients($account) {
$result = db_query("SELECT service, ticket, valid FROM {cas_server_tickets} WHERE uid=%d", array(
$account->uid,
));
$expired_tickets = array();
while ($client = db_fetch_object($result)) {
$expired_tickets[] = $client->ticket;
if (!$client->valid) {
$id = 'LR-' . user_password();
$date = date('c');
$logout_request = theme('cas_service_logout_request', $client->ticket, $date, $id);
$response = drupal_http_request($client->service, array(
'Content-Type' => 'application/x-www-form-urlencoded',
), 'POST', 'logoutRequest=' . urlencode($logout_request));
if (@$response->error) {
watchdog('error', 'Error in CAS logout Request - %code : %message', array(
'%code' => $response->code,
'%error' => $response->error,
));
}
}
}
if ($expired_tickets) {
db_query("DELETE FROM {cas_server_tickets} WHERE ticket IN (" . db_placeholders($expired_tickets, 'int') . ")", $expired_tickets);
}
}
function cas_server_user($op, &$edit, &$account, $category = NULL) {
if ($op == 'logout') {
cas_server_logout_clients($account);
}
}