Projet

Général

Profil

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

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

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', '2.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
    default:
37
      throw new Exception('Unknown CAS server version.');
38
      break;
39
  }
40

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

    
43
  // SAML not currently implemented.
44
  // phpCAS::setServerSamlValidateURL(url('cas_test/samlValidate', array('absolute' => TRUE)));
45
}
46

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

    
91
/**
92
 * Initiate a login request.
93
 *
94
 * Set the 'cas_test_cas_user' variable to an associative array containing:
95
 * - 'name': CAS username.
96
 * - 'attributes': (optional) Any other name-value pairs to be returned by the
97
 *   CAS server.
98
 */
99
function cas_test_login() {
100
  // Get the service and make a ticket.
101
  $service = $_REQUEST['service'];
102
  $cas_user = variable_get('cas_test_cas_user', '');
103

    
104
  if ($cas_user) {
105
    if (!is_array($cas_user)) {
106
      $cas_user = array('name' => $cas_user, 'attributes' => array());
107
    }
108
    // Generate a ticket and redirect to the service URL with the login ticket.
109
    $ticket = _cas_test_ticket_generate($service, $cas_user);
110
    // Force redirection.
111
    unset($_GET['destination']);
112
    drupal_goto($service, array('query' => array('ticket' => $ticket)));
113
  }
114
  elseif (isset($_GET['gateway']) && $_GET['gateway'] == 'true') {
115
    // We were not able to log in the user, so redirect to the service URL.
116
    // Force redirection.
117
    unset($_GET['destination']);
118
    drupal_goto($service);
119
  }
120
  else {
121
    // No CAS name was provided, print an error message.
122
    print "Warning: No CAS name provided.\n";
123
    exit();
124
  }
125
}
126

    
127
/**
128
 * Validate a ticket using the CAS 1.x protocol.
129
 */
130
function cas_test_validate() {
131
  // Prevent this page from being cached.
132
  drupal_page_is_cacheable(FALSE);
133

    
134
  // Set content type.
135
  drupal_add_http_header('Content-Type', 'text/plain; charset=utf-8');
136

    
137
  //Obtain the ticket from the url and validate it.
138
  $ticket = $_GET['ticket'];
139
  $service = $_GET['service'];
140
  $cas_user = _cas_test_ticket_validate($service, $ticket);
141
  if ($cas_user) {
142
    $cas_name = $cas_user['name'];
143
    print "yes\n";
144
    print "$cas_name\n";
145
  }
146
  else {
147
    print "no\n";
148
    print "\n";
149
  }
150
  exit();
151
}
152

    
153
/**
154
 * Validate a ticket using the CAS 2.0 protocol.
155
 */
156
function cas_test_service_validate() {
157
  // Prevent this page from being cached.
158
  drupal_page_is_cacheable(FALSE);
159

    
160
  // Set content type.
161
  drupal_add_http_header('Content-Type', 'text/xml; charset=utf-8');
162

    
163
  $ticket = $_GET['ticket'];
164
  $service = $_GET['service'];
165

    
166
  if ($cas_user = _cas_test_ticket_validate($service, $ticket)) {
167
    print theme('cas_service_validate_success', $cas_user);
168
  }
169
  else {
170
    $error_code = (!$ticket || !$service) ? 'INVALID_REQUEST' : 'INVALID_TICKET';
171
    print theme('cas_service_validate_failure', array('ticket' => $ticket, 'error_code' => $error_code));
172
  }
173
  exit();
174
}
175

    
176
/**
177
 * Log out a user.
178
 */
179
function cas_test_logout() {
180
  if (isset($_GET['url'])) {
181
    print t('Logged out. Continue to @url.', array('@url' => $_GET['url']));
182
  }
183
  else {
184
    print t('Logged out. No redirection provided.');
185
  }
186
  exit();
187
}
188

    
189
/**
190
 * Generate a login ticket.
191
 *
192
 * @param $service
193
 *   The service URL.
194
 * @param $cas_user
195
 *   An associative array containing the following keys:
196
 *     - 'name': The CAS username.
197
 *     - 'attributes': Any other key-value pairs the CAS server should return.
198
 *
199
 * @return
200
 *   A login ticket which may be used to authenticate the CAS username at the
201
 *   service URL.
202
 */
203
function _cas_test_ticket_generate($service, $cas_user) {
204
  // Generate a one-time ticket.
205
  $ticket = 'ST-' . user_password(32);
206

    
207
  // Save the ticket in the database.
208
  $tickets = variable_get('cas_test_tickets', array());
209
  $tickets[$service][$ticket] = $cas_user;
210
  variable_set('cas_test_tickets', $tickets);
211

    
212
  // Save the name in the database for single sign-out.
213
  $sso = variable_get('cas_test_sso', array());
214
  $sso[$cas_user['name']][$service][] = $ticket;
215
  variable_set('cas_test_sso', $sso);
216

    
217
  return $ticket;
218
}
219

    
220
/**
221
 * Validate a one-time-use login ticket.
222
 *
223
 * @param $service
224
 *   The service URL.
225
 * @param $ticket
226
 *   The login or proxy ticket.
227
 *
228
 * @return
229
 *   The CAS username corresponding to the ticket, or FALSE if the ticket is
230
 *   invalid.
231
 */
232
function _cas_test_ticket_validate($service, $ticket) {
233
  // Look up the ticket
234
  $cas_name = FALSE;
235
  $tickets = variable_get('cas_test_tickets', array());
236
  if (isset($tickets[$service][$ticket])) {
237
    $cas_name = $tickets[$service][$ticket];
238
    unset($tickets[$service][$ticket]);
239
  }
240
  return $cas_name;
241
}
242

    
243
/**
244
 * Sign out the specified CAS user.
245
 *
246
 * @param $cas_user
247
 */
248
function cas_test_single_sign_out($cas_name, $double_encode=FALSE) {
249
  $sso = variable_get('cas_test_sso', array());
250
  foreach ($sso[$cas_name] as $service => $tickets) {
251
    foreach ($tickets as $ticket) {
252
      // Generate posting:
253
      $data = array(
254
        '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)),
255
      );
256

    
257
      if ($double_encode) {
258
        // Certain CAS servers urlencode the logoutRequest.
259
        $data['logoutRequest'] = urlencode($data['logoutRequest']);
260
      }
261

    
262
      // Sign out the user.
263
      $options = array(
264
        'method' => 'POST',
265
        'headers' => array(
266
          'Content-Type' => 'application/x-www-form-urlencoded',
267
        ),
268
        'data' => drupal_http_build_query($data),
269
      );
270
      drupal_http_request($service, $options);
271
    }
272
  }
273
  unset($sso[$cas_name]);
274
  variable_set('cas_test_sso', $sso);
275
}
276

    
277
/**
278
 * Evaluate the specified token.
279
 */
280
function cas_test_token_evaluate() {
281
  print token_replace($_GET['token'], array('cas' => $_GET['name']));
282
  exit(0);
283
}