Projet

Général

Profil

Paste
Télécharger (8,7 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / cas / tests / cas_test.module @ 4f315dab

1
<?php
2

    
3
/**
4
 * @file
5
 * Dummy module implementing a CAS Server.
6
 */
7

    
8
/**
9
 *
10
 */
11
function cas_test_cas_phpcas_alter() {
12

    
13
  // Set the User-Agent field which is used by SimpleTest to identify testing
14
  // requests.
15
  $test_info = &$GLOBALS['drupal_test_info'];
16
  if (!empty($test_info['test_run_id'])) {
17
    phpCAS::setExtraCurlOption(CURLOPT_USERAGENT, drupal_generate_test_ua($test_info['test_run_id']));
18
  }
19

    
20
  // Set all CAS server URLs manually, as this is the only way to specify an
21
  // HTTP (i.e., not HTTPS) connection.
22
  $service_url = phpCAS::getServiceURL();
23
  phpCAS::setServerLoginURL(url('cas_test/login', array(
24
    'query' => array('service' => $service_url),
25
    'absolute' => TRUE,
26
  )));
27

    
28
  switch (variable_get('cas_version', '3.0')) {
29
    case CAS_VERSION_1_0:
30
      phpCAS::setServerServiceValidateURL(url('cas_test/validate', array('absolute' => TRUE)));
31
      break;
32
    case CAS_VERSION_2_0:
33
      phpCAS::setServerServiceValidateURL(url('cas_test/serviceValidate', array('absolute' => TRUE)));
34
      phpCAS::setServerProxyValidateURL(url('cas_test/proxyValidate',  array('absolute' => TRUE)));
35
      break;
36
    case CAS_VERSION_3_0:
37
      phpCAS::setServerServiceValidateURL(url('cas_test/p3/serviceValidate', array('absolute' => TRUE)));
38
      phpCAS::setServerProxyValidateURL(url('cas_test/p3/proxyValidate',  array('absolute' => TRUE)));
39
      break;
40
    default:
41
      throw new Exception('Unknown CAS server version.');
42
      break;
43
  }
44

    
45
  phpCAS::setServerLogoutURL(url('cas_test/logout',  array('absolute' => TRUE)));
46

    
47
  // SAML not currently implemented.
48
  // phpCAS::setServerSamlValidateURL(url('cas_test/samlValidate', array('absolute' => TRUE)));
49
}
50

    
51
/**
52
 * Implements hook_menu().
53
 */
54
function cas_test_menu() {
55
  $items = array();
56
  $items['cas_test/login'] = array(
57
    'page callback' => 'cas_test_login',
58
    'title' => 'CAS Login',
59
    'access callback' => TRUE,
60
    'type' => MENU_CALLBACK,
61
  );
62
  $items['cas_test/validate'] = array(
63
    'page callback' => 'cas_test_validate',
64
    'title' => 'CAS Validate',
65
    'access callback' => TRUE,
66
    'type' => MENU_CALLBACK,
67
  );
68
  $items['cas_test/serviceValidate'] = array(
69
    'page callback' => 'cas_test_service_validate',
70
    'title' => 'CAS Service Validate',
71
    'access callback' => TRUE,
72
    'type' => MENU_CALLBACK,
73
  );
74
  $items['cas_test/proxyValidate'] = array(
75
    'page callback' => 'cas_test_service_validate',
76
    'title' => 'CAS Proxy Ticket Validate',
77
    'access callback' => TRUE,
78
    'type' => MENU_CALLBACK,
79
  );
80
  $items['cas_test/p3/serviceValidate'] = array(
81
    'page callback' => 'cas_test_service_validate',
82
    'title' => 'CAS 3.0 Service Validate',
83
    'access callback' => TRUE,
84
    'type' => MENU_CALLBACK,
85
  );
86
  $items['cas_test/p3/proxyValidate'] = array(
87
    'page callback' => 'cas_test_service_validate',
88
    'title' => 'CAS 3.0 Proxy Ticket Validate',
89
    'access callback' => TRUE,
90
    'type' => MENU_CALLBACK,
91
  );
92
  $items['cas_test/logout'] = array(
93
    'page callback' => 'cas_test_logout',
94
    'title' => 'CAS Logout',
95
    'access callback' => TRUE,
96
    'type' => MENU_CALLBACK,
97
  );
98
  $items['cas_test/token'] = array(
99
    'page callback' => 'cas_test_token_evaluate',
100
    'title' => 'CAS Token Test',
101
    'access callback' => TRUE,
102
    'type' => MENU_CALLBACK,
103
  );
104
  return $items;
105
}
106

    
107
/**
108
 * Initiate a login request.
109
 *
110
 * Set the 'cas_test_cas_user' variable to an associative array containing:
111
 * - 'name': CAS username.
112
 * - 'attributes': (optional) Any other name-value pairs to be returned by the
113
 *   CAS server.
114
 */
115
function cas_test_login() {
116
  // Get the service and make a ticket.
117
  $service = $_REQUEST['service'];
118
  $cas_user = variable_get('cas_test_cas_user', '');
119

    
120
  if ($cas_user) {
121
    if (!is_array($cas_user)) {
122
      $cas_user = array('name' => $cas_user, 'attributes' => array());
123
    }
124
    // Generate a ticket and redirect to the service URL with the login ticket.
125
    $ticket = _cas_test_ticket_generate($service, $cas_user);
126
    // Force redirection.
127
    unset($_GET['destination']);
128
    drupal_goto($service, array('query' => array('ticket' => $ticket)));
129
  }
130
  elseif (isset($_GET['gateway']) && $_GET['gateway'] == 'true') {
131
    // We were not able to log in the user, so redirect to the service URL.
132
    // Force redirection.
133
    unset($_GET['destination']);
134
    drupal_goto($service);
135
  }
136
  else {
137
    // No CAS name was provided, print an error message.
138
    print "Warning: No CAS name provided.\n";
139
    exit();
140
  }
141
}
142

    
143
/**
144
 * Validate a ticket using the CAS 1.x protocol.
145
 */
146
function cas_test_validate() {
147
  // Prevent this page from being cached.
148
  drupal_page_is_cacheable(FALSE);
149

    
150
  // Set content type.
151
  drupal_add_http_header('Content-Type', 'text/plain; charset=utf-8');
152

    
153
  //Obtain the ticket from the url and validate it.
154
  $ticket = $_GET['ticket'];
155
  $service = $_GET['service'];
156
  $cas_user = _cas_test_ticket_validate($service, $ticket);
157
  if ($cas_user) {
158
    $cas_name = $cas_user['name'];
159
    print "yes\n";
160
    print "$cas_name\n";
161
  }
162
  else {
163
    print "no\n";
164
    print "\n";
165
  }
166
  exit();
167
}
168

    
169
/**
170
 * Validate a ticket using the CAS 2.0 and CAS 3.0 protocols.
171
 */
172
function cas_test_service_validate() {
173
  // Prevent this page from being cached.
174
  drupal_page_is_cacheable(FALSE);
175

    
176
  // Set content type.
177
  drupal_add_http_header('Content-Type', 'text/xml; charset=utf-8');
178

    
179
  $ticket = $_GET['ticket'];
180
  $service = $_GET['service'];
181

    
182
  if ($cas_user = _cas_test_ticket_validate($service, $ticket)) {
183
    print theme('cas_service_validate_success', $cas_user);
184
  }
185
  else {
186
    $error_code = (!$ticket || !$service) ? 'INVALID_REQUEST' : 'INVALID_TICKET';
187
    print theme('cas_service_validate_failure', array('ticket' => $ticket, 'error_code' => $error_code));
188
  }
189
  exit();
190
}
191

    
192
/**
193
 * Log out a user.
194
 */
195
function cas_test_logout() {
196
  if (isset($_GET['url'])) {
197
    print t('Logged out. Continue to @url.', array('@url' => $_GET['url']));
198
  }
199
  else {
200
    print t('Logged out. No redirection provided.');
201
  }
202
  exit();
203
}
204

    
205
/**
206
 * Generate a login ticket.
207
 *
208
 * @param $service
209
 *   The service URL.
210
 * @param $cas_user
211
 *   An associative array containing the following keys:
212
 *     - 'name': The CAS username.
213
 *     - 'attributes': Any other key-value pairs the CAS server should return.
214
 *
215
 * @return
216
 *   A login ticket which may be used to authenticate the CAS username at the
217
 *   service URL.
218
 */
219
function _cas_test_ticket_generate($service, $cas_user) {
220
  // Generate a one-time ticket.
221
  $ticket = 'ST-' . user_password(32);
222

    
223
  // Save the ticket in the database.
224
  $tickets = variable_get('cas_test_tickets', array());
225
  $tickets[$service][$ticket] = $cas_user;
226
  variable_set('cas_test_tickets', $tickets);
227

    
228
  // Save the name in the database for single sign-out.
229
  $sso = variable_get('cas_test_sso', array());
230
  $sso[$cas_user['name']][$service][] = $ticket;
231
  variable_set('cas_test_sso', $sso);
232

    
233
  return $ticket;
234
}
235

    
236
/**
237
 * Validate a one-time-use login ticket.
238
 *
239
 * @param $service
240
 *   The service URL.
241
 * @param $ticket
242
 *   The login or proxy ticket.
243
 *
244
 * @return
245
 *   The CAS username corresponding to the ticket, or FALSE if the ticket is
246
 *   invalid.
247
 */
248
function _cas_test_ticket_validate($service, $ticket) {
249
  // Look up the ticket
250
  $cas_name = FALSE;
251
  $tickets = variable_get('cas_test_tickets', array());
252
  if (isset($tickets[$service][$ticket])) {
253
    $cas_name = $tickets[$service][$ticket];
254
    unset($tickets[$service][$ticket]);
255
  }
256
  return $cas_name;
257
}
258

    
259
/**
260
 * Sign out the specified CAS user.
261
 *
262
 * @param $cas_user
263
 */
264
function cas_test_single_sign_out($cas_name, $double_encode=FALSE) {
265
  $sso = variable_get('cas_test_sso', array());
266
  foreach ($sso[$cas_name] as $service => $tickets) {
267
    foreach ($tickets as $ticket) {
268
      // Generate posting:
269
      $data = array(
270
        'logoutRequest' => t("<samlp:LogoutRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" 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)),
271
      );
272

    
273
      if ($double_encode) {
274
        // Certain CAS servers urlencode the logoutRequest.
275
        $data['logoutRequest'] = urlencode($data['logoutRequest']);
276
      }
277

    
278
      // Sign out the user.
279
      $options = array(
280
        'method' => 'POST',
281
        'headers' => array(
282
          'Content-Type' => 'application/x-www-form-urlencoded',
283
        ),
284
        'data' => drupal_http_build_query($data),
285
      );
286
      drupal_http_request($service, $options);
287
    }
288
  }
289
  unset($sso[$cas_name]);
290
  variable_set('cas_test_sso', $sso);
291
}
292

    
293
/**
294
 * Evaluate the specified token.
295
 */
296
function cas_test_token_evaluate() {
297
  print token_replace($_GET['token'], array('cas' => $_GET['name']));
298
  exit(0);
299
}