Projet

Général

Profil

Paste
Télécharger (6,82 ko) Statistiques
| Branche: | Révision:

root / htmltest / sites / all / modules / cas / cas_server.module @ c12e7e6a

1
<?php
2

    
3
/**
4
 * @file Provides a protocol compliant version of CAS server 2.x
5
 */
6
define('CAS_LOGIN_COOKIE', 'cas_server_login');
7

    
8
/**
9
 * Implementation of hook_menu
10
 */
11
function cas_server_menu() {
12
  $items = array();
13
  $items['cas/login'] = array(
14
    'page callback' => 'cas_server_login',
15
    'title' => 'CAS Login',
16
    'access callback' => TRUE,
17
    'type' => MENU_CALLBACK,
18
  );
19

    
20
  $items['cas/validate'] = array(
21
    'page callback' => 'cas_server_validate',
22
    'title' => 'CAS Validate',
23
    'access callback' => TRUE,
24
    'type' => MENU_CALLBACK,
25
  );
26

    
27
  $items['cas/serviceValidate'] = array(
28
    'page callback' => 'cas_server_service_validate',
29
    'title' => 'CAS Service Validate',
30
    'access callback' => TRUE,
31
    'type' => MENU_CALLBACK,
32
  );
33

    
34
  $items['cas/proxyValidate'] = array(
35
    'page callback' => 'cas_server_service_validate',
36
    'title' => 'CAS Proxy Ticket Validate',
37
    'access callback' => TRUE,
38
    'type' => MENU_CALLBACK,
39
  );
40

    
41
  $items['cas/logout'] = array(
42
    'page callback' => 'cas_server_logout',
43
    'title' => 'CAS Logout',
44
    'access callback' => TRUE,
45
    'type' => MENU_CALLBACK,
46
  );
47
  return $items;
48
}
49

    
50
/**
51
 * Implements hook_theme().
52
 */
53
function cas_server_theme() {
54
  return array(
55
    'cas_service_validate_success' => array(
56
      'variables' => array('name' => NULL, 'attributes' => NULL),
57
      'file' => 'cas_server.response.inc',
58
    ),
59
    'cas_service_validate_attributes' => array(
60
      'variables' => array('attributes' => NULL, 'style' => 'jasig'),
61
      'file' => 'cas_server.response.inc',
62
    ),
63
    'cas_service_validate_failure' => array(
64
      'variables' => array('ticket' => NULL, 'error_code' => NULL),
65
      'file' => 'cas_server.response.inc',
66
    ),
67
  );
68
}
69

    
70
/**
71
 * Implements hook_cas_server_user_attributes().
72
 *
73
 * Returns the user's roles.
74
 */
75
function cas_server_cas_server_user_attributes($account, $service) {
76
  return array(
77
    'uid'           => $account->uid,
78
    'mail'          => $account->mail,
79
    'created'       => $account->created,
80
    'timezone'      => $account->timezone,
81
    'language'      => $account->language,
82
    'drupal_roles'  => $account->roles,
83
  );
84
}
85

    
86
function cas_server_service_return() {
87
  global $user;
88
  $service = isset($_COOKIE[CAS_LOGIN_COOKIE]) ? $_COOKIE[CAS_LOGIN_COOKIE] : '';
89
  if ($service && $user->uid) {
90
    $ticket = _cas_server_save_ticket($user->uid, $service);
91
    setcookie(CAS_LOGIN_COOKIE, "", -3600);
92
    drupal_goto($service, array('query' => array('ticket' => $ticket)));
93
  }
94
}
95

    
96
/**
97
 * Handle login
98
 *
99
 */
100
function cas_server_login() {
101
  // Set login cookie so that we know we're in the process of logging in
102
  global $user;
103
  $output='';
104
  $service = isset($_REQUEST['service']) ? $_REQUEST['service'] : '';
105
  $gateway = isset($_REQUEST['gateway']);
106
  if ($user->uid) {
107
    if ($service) {
108
      $_COOKIE[CAS_LOGIN_COOKIE] = $service;
109
    }
110
    $output=t('You have successfully logged into CAS');
111
    cas_server_service_return();
112
  }
113
  else {
114
    if ($gateway && $service) {
115
      drupal_goto($service);
116
    }
117
    else {
118
      // Redirect to user login
119
      if ($service) {
120
        setcookie(CAS_LOGIN_COOKIE, $service);
121
      }
122
      $output .= l(t('Login'), 'user', array('query' => array('destination' => 'cas/login')));
123
      drupal_goto('user', array('query' => array('destination' => 'cas/login')));
124
    }
125
  }
126
  return $output;
127
}
128

    
129
/**
130
 * Validate the ticket using a CAS 1.x methodology
131
 * This provides the simple non-xml based
132
 */
133
function cas_server_validate() {
134
  //Obtain the ticket from the url and validate it.
135
  $ticket = isset($_REQUEST['ticket']) ? $_REQUEST['ticket'] : '';
136
  $service = isset($_REQUEST['service']) ? $_REQUEST['service'] : '';
137
  $user_name = _cas_server_validate($service, $ticket);
138
  if ($user_name) {
139
    print "yes\n";
140
    print "$user_name\n";
141
  }
142
  else {
143
    print "no\n";
144
    print "\n";
145
  }
146
}
147
/**
148
 * serviceValidate method using cas 2.0
149
 * Returns data in xml
150
 */
151
function cas_server_service_validate() {
152
  $ticket = isset($_REQUEST['ticket']) ? $_REQUEST['ticket'] : '';
153
  $service = isset($_REQUEST['service']) ? $_REQUEST['service'] : '';
154
  $user_name = _cas_server_validate($service, $ticket);
155
  if (!$user_name) $cas_error='INVALID_TICKET';
156
  if (!$ticket || !$service) $cas_error='INVALID_REQUEST';
157

    
158
  header('Content-type:', 'text/xml');
159
  if ($user_name) {
160
    //@TODO Generate proxy granting ticket
161
    $account = user_load_by_name($user_name);
162

    
163
    // Generate a list of attributes to return.
164
    $attributes = module_invoke_all('cas_server_user_attributes', $account, $service, $ticket);
165

    
166
    // Let other modules alter the list of attributes.
167
    $context = array(
168
      'service' => $service,
169
      'ticket' => $ticket,
170
    );
171
    drupal_alter('cas_server_user_attributes', $attributes, $account, $context);
172

    
173
    print theme('cas_service_validate_success', array('name' => $user_name, 'attributes' => $attributes));
174
    watchdog('cas', 'User %name CAS sucessully authenticated.', array('%name' => $user_name));
175
  }
176
  else {
177
    print theme('cas_service_validate_failure', array('ticket' => $ticket, 'error_code' => $cas_error));
178
    watchdog('cas', 'Ticket %ticket for service %service not recognized.', array('%ticket' => $ticket, '%service' => $service));
179
  }
180
}
181

    
182
/**
183
 * Test to see if a one time use ticket is valid
184
 *
185
 * @param unknown_type $ticket
186
 * @return unknown
187
 */
188
function _cas_server_validate($service, $ticket) {
189
  // Look up the ticket
190
  $user_name='';
191
  $ticket_info=array(':service' => $service, ':ticket' => $ticket);
192
  $result = db_query_range("SELECT u.name FROM {cas_server_tickets} t JOIN {users} u ON t.uid=u.uid  WHERE t.service = :service and t.ticket = :ticket", 0, 1, $ticket_info);
193
  if ($result !== FALSE) {
194
    foreach ($result as $ticket_data) {
195
      $user_name = $ticket_data->name;
196
    }
197
  }
198
  db_delete('cas_server_tickets')
199
    ->condition('ticket', $ticket)
200
    ->execute();
201

    
202
  return $user_name;
203
}
204

    
205
/**
206
 * Generate a one time use login ticket for the user in question.
207
 *
208
 * @param int $uid
209
 */
210
function _cas_server_save_ticket($uid, $service) {
211
  // Generate the ticket
212
  $time = REQUEST_TIME;
213
  $ticket = 'ST-' . user_password();
214
  $ticket_data = array('uid' => $uid, 'service' => $service, 'ticket' => $ticket, 'timestamp' => $time);
215
  // Save the ticket to the db
216
  if ($uid && $service) {
217
    db_insert('cas_server_tickets')->fields($ticket_data)->execute();
218
  }
219
  return $ticket;
220
}
221

    
222
/**
223
 * Menu callback; triggers a CAS logout.
224
 *
225
 * @TODO: Implement single sign out support
226
 */
227
function cas_server_logout() {
228
  global $user;
229

    
230
  watchdog('user', 'Session closed for %name.', array('%name' => $user->name));
231

    
232
  module_invoke_all('user_logout', $user);
233

    
234
  // Destroy the current session, and reset $user to the anonymous user.
235
  session_destroy();
236

    
237
  $output = '<p>' . t('You have been logged out successfully.') . '</p>';
238
  if (isset($_REQUEST['url'])) {
239
    $output .= '<p>' . l(t('Continue'), $_REQUEST['url']) . '</p>';
240
  }
241
  return $output;
242
}