Révision a2baadd1
Ajouté par Assos Assos il y a environ 10 ans
drupal7/sites/all/modules/cas/cas.admin.inc | ||
---|---|---|
310 | 310 |
), |
311 | 311 |
), |
312 | 312 |
); |
313 |
|
|
313 | 314 |
$form['advanced']['cas_proxy_settings']['cas_pgtformat'] = array( |
314 | 315 |
'#type' => 'radios', |
315 | 316 |
'#title' => t('CAS PGT storage file format'), |
316 | 317 |
'#default_value' => variable_get('cas_pgtformat', 'plain'), |
317 | 318 |
'#options' => array('plain' => t('Plain Text'), 'xml' => t('XML')), |
319 |
'#after_build' => array('cas_pgtformat_version_check'), |
|
318 | 320 |
); |
319 | 321 |
|
320 | 322 |
$form['advanced']['cas_proxy_settings']['cas_pgtpath'] = array( |
... | ... | |
325 | 327 |
'#description' => t("Only needed if 'Use CAS proxy initializer' is configured. Leave empty for default."), |
326 | 328 |
); |
327 | 329 |
|
330 |
$form['advanced']['cas_proxy_list'] = array( |
|
331 |
'#type' => 'textarea', |
|
332 |
'#title' => t('CAS proxy list'), |
|
333 |
'#description' => t("If CAS client could be proxied, indicate each proxy server absolute url per line. If not provided, phpCAS will exclude by default all tickets provided by proxy. Each proxy server url could be a plain url or a regular expression. IMPORTANT : regular expression delimiter must be a slash. For example : https://proxy.example.com/ AND/OR regular expression : /^https:\/\/app[0-9]\.example\.com\/rest\//."), |
|
334 |
'#default_value' => variable_get('cas_proxy_list', ''), |
|
335 |
'#after_build' => array('cas_proxy_list_version_check'), |
|
336 |
); |
|
337 |
|
|
328 | 338 |
$form['advanced']['cas_debugfile'] = array( |
329 | 339 |
'#type' => 'textfield', |
330 | 340 |
'#title' => t('CAS debugging output filename'), |
... | ... | |
359 | 369 |
} |
360 | 370 |
return $element; |
361 | 371 |
} |
372 |
|
|
373 |
/** |
|
374 |
* Proxy chain object only exists with phpCAS version >= 1.3. As phpCAS CAS.php |
|
375 |
* is include only after building element 'cas_library_dir', we must check it after it. |
|
376 |
*/ |
|
377 |
function cas_proxy_list_version_check($element, &$form_state) { |
|
378 |
if (!defined('PHPCAS_VERSION') || version_compare(PHPCAS_VERSION, '1.3', '<')) { |
|
379 |
$element['#access'] = FALSE; |
|
380 |
} |
|
381 |
return $element; |
|
382 |
} |
|
383 |
|
|
384 |
/** |
|
385 |
* Since 1.3, pgt format isn't supported and default to plain. |
|
386 |
*/ |
|
387 |
function cas_pgtformat_version_check($element, &$form_state) { |
|
388 |
if (!defined('PHPCAS_VERSION') || version_compare(PHPCAS_VERSION, '1.3', '>')) { |
|
389 |
$element['#access'] = FALSE; |
|
390 |
} |
|
391 |
return $element; |
|
392 |
} |
drupal7/sites/all/modules/cas/cas.drush.inc | ||
---|---|---|
10 | 10 |
*/ |
11 | 11 |
function cas_drush_command() { |
12 | 12 |
$items = array(); |
13 |
$items['cas-user-add-role'] = array( |
|
14 |
'callback' => 'cas_drush_user_add_role', |
|
15 |
'description' => 'Add a role to the specified CAS usernames.', |
|
16 |
'arguments' => array( |
|
17 |
'role' => 'The name of the role to add', |
|
18 |
'users' => '(optional) A comma delimited list of CAS user names.', |
|
19 |
), |
|
20 |
'required-arguments' => 1, |
|
21 |
'examples' => array( |
|
22 |
'drush cas-user-add-role "power user" casuser1,casuser2' => |
|
23 |
'Add the "power user" role to the accounts with CAS user names casuser1 and casuser2.', |
|
24 |
), |
|
25 |
); |
|
13 | 26 |
$items['cas-user-create'] = array( |
14 | 27 |
'callback' => 'cas_drush_user_create', |
15 | 28 |
'description' => dt('Create a CAS user account with the specified CAS username.'), |
... | ... | |
25 | 38 |
} |
26 | 39 |
|
27 | 40 |
/** |
28 |
* Implementats hook_drush_help().
|
|
41 |
* Implements hook_drush_help(). |
|
29 | 42 |
*/ |
30 | 43 |
function cas_drush_help($section) { |
31 | 44 |
switch ($section) { |
32 | 45 |
case 'drush:cas-user-create': |
33 | 46 |
return dt('Create a CAS user account with the specified CAS username.'); |
47 |
case 'drush:cas-user-add-role': |
|
48 |
return dt('Add a role to the specified CAS usernames.'); |
|
34 | 49 |
} |
35 | 50 |
} |
36 | 51 |
|
... | ... | |
57 | 72 |
drush_set_error(dt('There is already a user account with CAS username @cas_name.', array('@cas_name' => $cas_name))); |
58 | 73 |
} |
59 | 74 |
} |
75 |
|
|
76 |
/** |
|
77 |
* Add a role to the specified CAS user accounts. |
|
78 |
*/ |
|
79 |
function cas_drush_user_add_role($role, $users = '') { |
|
80 |
$uids = cas_drush_user_get_users_from_arguments($users); |
|
81 |
if (drush_drupal_major_version() >= 7) { |
|
82 |
$rid_query = db_query("SELECT rid FROM {role} WHERE name = :role", array(':role' => $role)); |
|
83 |
} |
|
84 |
else { |
|
85 |
$rid_query = db_query("SELECT rid FROM {role} WHERE name = '%s'", $role); |
|
86 |
} |
|
87 |
if (!empty($uids)) { |
|
88 |
if ($rid = drush_db_result($rid_query)) { |
|
89 |
drush_op('user_multiple_role_edit', $uids, 'add_role', $rid); |
|
90 |
foreach ($uids as $uid) { |
|
91 |
drush_log(dt("Added the !role role to uid !uid", array('!role' => $role, '!uid' => $uid)), 'success'); |
|
92 |
} |
|
93 |
} |
|
94 |
else { |
|
95 |
return drush_set_error(dt("There is no role named: !role", array('!role' => $role))); |
|
96 |
} |
|
97 |
} |
|
98 |
else { |
|
99 |
return drush_set_error("Could not find any valid uids!"); |
|
100 |
} |
|
101 |
} |
|
102 |
|
|
103 |
/** |
|
104 |
* Look up user ids from a comma-separated list of CAS usernames. |
|
105 |
* |
|
106 |
* @param $users string |
|
107 |
* Comma separated list of CAS usernames. |
|
108 |
* |
|
109 |
* @return array |
|
110 |
* An array of user ids corresponding to the given CAS usernames. Unknown |
|
111 |
* CAS usernames are ignored. |
|
112 |
*/ |
|
113 |
function cas_drush_user_get_users_from_arguments($users) { |
|
114 |
$uids = array(); |
|
115 |
if ($users !== '') { |
|
116 |
$users = explode(',', $users); |
|
117 |
foreach ($users as $user) { |
|
118 |
$account = cas_user_load_by_name($user); |
|
119 |
if ($account) { |
|
120 |
$uids[] = $account->uid; |
|
121 |
} |
|
122 |
} |
|
123 |
} |
|
124 |
return $uids; |
|
125 |
} |
drupal7/sites/all/modules/cas/cas.info | ||
---|---|---|
7 | 7 |
files[] = cas.test |
8 | 8 |
files[] = includes/views/handlers/cas_handler_field_cas_name.inc |
9 | 9 |
|
10 |
; Information added by drupal.org packaging script on 2012-05-09
|
|
11 |
version = "7.x-1.2"
|
|
10 |
; Information added by Drupal.org packaging script on 2014-04-02
|
|
11 |
version = "7.x-1.3"
|
|
12 | 12 |
core = "7.x" |
13 | 13 |
project = "cas" |
14 |
datestamp = "1336595150"
|
|
14 |
datestamp = "1396458247"
|
|
15 | 15 |
|
drupal7/sites/all/modules/cas/cas.install | ||
---|---|---|
99 | 99 |
variable_del('cas_pgtpath'); |
100 | 100 |
variable_del('cas_port'); |
101 | 101 |
variable_del('cas_proxy'); |
102 |
variable_del('cas_proxy_list'); |
|
102 | 103 |
variable_del('cas_registerURL'); |
103 | 104 |
variable_del('cas_server'); |
104 | 105 |
variable_del('cas_uri'); |
drupal7/sites/all/modules/cas/cas.module | ||
---|---|---|
99 | 99 |
if (empty($cas_user['login']) || empty($cas_user['name'])) { |
100 | 100 |
// Only set a warning if we forced login. |
101 | 101 |
if ($force_authentication) { |
102 |
drupal_set_message(t('The user account %name is not available on this site.', array('%name' => $cas_name)), 'error');
|
|
102 |
drupal_set_message(t('The user account %name is not available on this site.', array('%name' => $cas_user['name'])), 'error');
|
|
103 | 103 |
} |
104 | 104 |
return; |
105 | 105 |
} |
... | ... | |
159 | 159 |
$edit['cas_user'] = $cas_user; |
160 | 160 |
$edit['roles'] = $account->roles + cas_roles(); |
161 | 161 |
if (module_exists('persistent_login') && !empty($_SESSION['cas_remember'])) { |
162 |
$edit['persistent_login'] = 1; |
|
162 |
$edit['values']['persistent_login'] = 1;
|
|
163 | 163 |
} |
164 | 164 |
// Allow other modules to make their own custom changes. |
165 | 165 |
cas_user_module_invoke('presave', $edit, $account); |
... | ... | |
179 | 179 |
$user = drupal_anonymous_user(); |
180 | 180 |
// Only display error messages only if the user intended to log in. |
181 | 181 |
if ($force_authentication) { |
182 |
drupal_set_message(t('No account found for %cas_name.', array('%cas_name' => $cas_name))); |
|
182 |
drupal_set_message(t('No account found for %cas_name.', array('%cas_name' => $cas_name)), 'error');
|
|
183 | 183 |
} |
184 | 184 |
} |
185 | 185 |
} |
... | ... | |
243 | 243 |
$server_port = (int)variable_get('cas_port', '443'); |
244 | 244 |
$server_uri = (string)variable_get('cas_uri', ''); |
245 | 245 |
$cas_cert = (string)variable_get('cas_cert', ''); |
246 |
if ( ($debugFile = variable_get("cas_debugfile", "")) != "" ) { |
|
247 |
phpCAS::setDebug($debugFile); |
|
246 |
$debug_file = (string)variable_get('cas_debugfile', ''); |
|
247 |
if ($debug_file != '') { |
|
248 |
phpCAS::setDebug($debug_file); |
|
248 | 249 |
} |
249 | 250 |
$start_session = (boolean)FALSE; |
250 |
if ( variable_get("cas_proxy", 0) ) {
|
|
251 |
if (variable_get('cas_proxy', 0)) {
|
|
251 | 252 |
phpCAS::proxy($server_version, $server_cas_server, $server_port, $server_uri, $start_session); |
252 |
$casPGTStoragePath = variable_get("cas_pgtpath", ""); |
|
253 |
if ( $casPGTStoragePath != "" ) { |
|
254 |
$casPGTFormat = variable_get("cas_pgtformat", "plain"); |
|
255 |
phpCAS::setPGTStorageFile($casPGTFormat, $casPGTStoragePath); |
|
253 |
$cas_pgt_storage_path = variable_get('cas_pgtpath', ''); |
|
254 |
if ($cas_pgt_storage_path != '') { |
|
255 |
if (version_compare(PHPCAS_VERSION, '1.3', '>=')) { |
|
256 |
phpCAS::setPGTStorageFile($cas_pgt_storage_path); |
|
257 |
} |
|
258 |
else { |
|
259 |
$cas_pgt_format = variable_get('cas_pgtformat', 'plain'); |
|
260 |
phpCAS::setPGTStorageFile($cas_pgt_format, $cas_pgt_storage_path); |
|
261 |
} |
|
256 | 262 |
} |
257 | 263 |
} |
258 | 264 |
else { |
259 | 265 |
phpCAS::client($server_version, $server_cas_server, $server_port, $server_uri, $start_session); |
260 | 266 |
} |
267 |
|
|
268 |
//Add CAS proxy lists allowed |
|
269 |
$proxy_list = variable_get('cas_proxy_list', ''); |
|
270 |
if ($proxy_list) { |
|
271 |
$proxy_list = explode("\n", $proxy_list); |
|
272 |
phpCAS::allowProxyChain(new CAS_ProxyChain($proxy_list)); |
|
273 |
} |
|
274 |
|
|
261 | 275 |
// force CAS authentication |
262 | 276 |
if ($cas_cert = variable_get('cas_cert', '')) { |
263 | 277 |
phpCAS::setCasServerCACert($cas_cert); |
... | ... | |
380 | 394 |
* Implements hook_menu_link_alter(). |
381 | 395 |
* |
382 | 396 |
* Flag this link as needing alter at display time. |
383 |
* @see cas_translated_menu_link_alter().
|
|
384 |
**/
|
|
397 |
* @see cas_translated_menu_link_alter() |
|
398 |
*/ |
|
385 | 399 |
function cas_menu_link_alter(&$item) { |
386 | 400 |
if ($item['link_path'] == 'cas' || $item['link_path'] == 'caslogout') { |
387 | 401 |
$item['options']['alter'] = TRUE; |
... | ... | |
392 | 406 |
* Implements hook_translated_menu_item_alter(). |
393 | 407 |
* |
394 | 408 |
* Append dynamic query 'destination' to several menu items. |
395 |
**/
|
|
409 |
*/ |
|
396 | 410 |
function cas_translated_menu_link_alter(&$item) { |
397 | 411 |
if ($item['href'] == 'cas') { |
398 | 412 |
$item['localized_options']['query'] = drupal_get_destination(); |
... | ... | |
437 | 451 |
* An array of user ids. For each account, a CAS username is created with |
438 | 452 |
* the same name as the Drupal username. |
439 | 453 |
* |
440 |
* @see cas_user_operations().
|
|
454 |
* @see cas_user_operations() |
|
441 | 455 |
*/ |
442 | 456 |
function cas_user_operations_create_username($uids) { |
443 | 457 |
$accounts = user_load_multiple($uids); |
... | ... | |
463 | 477 |
* @param $uids |
464 | 478 |
* An array of user ids. For each account, all CAS usernames are removed. |
465 | 479 |
* |
466 |
* @see cas_user_operations().
|
|
480 |
* @see cas_user_operations() |
|
467 | 481 |
*/ |
468 | 482 |
function cas_user_operations_remove_usernames($uids) { |
469 | 483 |
db_delete('cas_user') |
... | ... | |
590 | 604 |
* @param $alter |
591 | 605 |
* If TRUE, run the CAS username through hook_cas_user_alter() before |
592 | 606 |
* loading the account. |
607 |
* @param $reset |
|
608 |
* TRUE to reset the internal cache and load from the database; FALSE |
|
609 |
* (default) to load from the internal cache, if set. |
|
593 | 610 |
* |
594 | 611 |
* @return |
595 | 612 |
* A fully-loaded $user object upon successful user load or FALSE if user |
596 | 613 |
* cannot be loaded. |
597 | 614 |
*/ |
598 |
function cas_user_load_by_name($cas_name, $alter = FALSE) { |
|
615 |
function cas_user_load_by_name($cas_name, $alter = FALSE, $reset = FALSE) {
|
|
599 | 616 |
if ($alter) { |
600 | 617 |
$cas_user = array( |
601 | 618 |
'name' => $cas_name, |
... | ... | |
606 | 623 |
$cas_name = $cas_user['name']; |
607 | 624 |
} |
608 | 625 |
|
609 |
$uid = db_query("SELECT uid FROM {cas_user} WHERE cas_name = :cas_name", array(':cas_name' => $cas_name))->fetchField();
|
|
626 |
$uid = db_select('cas_user')->fields('cas_user', array('uid'))->condition('cas_name', db_like($cas_name), 'LIKE')->range(0, 1)->execute()->fetchField();
|
|
610 | 627 |
if ($uid) { |
611 |
return user_load($uid); |
|
628 |
return user_load($uid, $reset);
|
|
612 | 629 |
} |
613 | 630 |
return FALSE; |
614 | 631 |
} |
... | ... | |
623 | 640 |
function cas_login_page($cas_first_login = FALSE) { |
624 | 641 |
global $user; |
625 | 642 |
$destination = ''; |
643 |
$query = array(); |
|
626 | 644 |
// If it is the user's first CAS login and initial login redirection is enabled, go to the set page |
627 | 645 |
if ($cas_first_login && variable_get('cas_first_login_destination', '')) { |
628 | 646 |
$destination = variable_get('cas_first_login_destination', ''); |
647 |
if (isset($_GET['destination'])) |
|
648 |
$query['destination'] = $_GET['destination']; |
|
629 | 649 |
unset($_GET['destination']); |
630 | 650 |
} |
631 | 651 |
|
632 | 652 |
// Respect the query string, if transmitted. |
633 |
drupal_goto($destination); |
|
653 |
drupal_goto($destination, array('query' => $query));
|
|
634 | 654 |
} |
635 | 655 |
|
636 | 656 |
/** |
... | ... | |
654 | 674 |
|
655 | 675 |
// Build the logout URL. |
656 | 676 |
cas_phpcas_init(); |
657 |
$logout_url = phpCAS::getServerLogoutURL(); |
|
658 |
$options = array(); |
|
659 | 677 |
|
660 | 678 |
if (isset($_GET['destination']) && !url_is_external($_GET['destination'])) { |
661 | 679 |
// Add destination override so that a destination can be specified on the |
... | ... | |
671 | 689 |
//Make it an absolute url. This will also convert <front> to the front page. |
672 | 690 |
if ($destination) { |
673 | 691 |
$destination_url = url($destination, array('absolute' => TRUE)); |
674 |
$options['query'] = array( |
|
675 |
'destination' => $destination_url, |
|
692 |
$options = array( |
|
676 | 693 |
'service' => $destination_url, |
677 | 694 |
'url' => $destination_url, |
678 | 695 |
); |
679 | 696 |
} |
697 |
else { |
|
698 |
$options = array(); |
|
699 |
} |
|
680 | 700 |
|
681 | 701 |
// Mimic user_logout(). |
682 | 702 |
if ($invoke_hook) { |
683 | 703 |
watchdog('user', 'Session closed for %name.', array('%name' => $user->name)); |
684 | 704 |
module_invoke_all('user_logout', $user); |
685 | 705 |
} |
686 |
session_destroy(); |
|
687 | 706 |
|
688 |
// Force redirection in drupal_goto(). |
|
689 |
unset($_GET['destination']); |
|
690 |
drupal_goto($logout_url, $options); |
|
707 |
// phpCAS automatically calls session_destroy(). |
|
708 |
phpCAS::logout($options); |
|
691 | 709 |
} |
692 | 710 |
|
693 | 711 |
/** |
... | ... | |
745 | 763 |
* Determine if we should automatically check if the user is authenticated. |
746 | 764 |
* |
747 | 765 |
* This implements part of the CAS gateway feature. |
748 |
* @see phpCAS::checkAuthentication().
|
|
766 |
* @see phpCAS::checkAuthentication() |
|
749 | 767 |
* |
750 | 768 |
* @return |
751 | 769 |
* TRUE if we should query the CAS server to see if the user is already |
... | ... | |
763 | 781 |
} |
764 | 782 |
|
765 | 783 |
// Check to see if we've got a search bot. |
766 |
$crawlers = array( |
|
767 |
'Google', |
|
768 |
'msnbot', |
|
769 |
'Rambler', |
|
770 |
'Yahoo', |
|
771 |
'AbachoBOT', |
|
772 |
'accoona', |
|
773 |
'AcoiRobot', |
|
774 |
'ASPSeek', |
|
775 |
'CrocCrawler', |
|
776 |
'Dumbot', |
|
777 |
'FAST-WebCrawler', |
|
778 |
'GeonaBot', |
|
779 |
'Gigabot', |
|
780 |
'Lycos', |
|
781 |
'MSRBOT', |
|
782 |
'Scooter', |
|
783 |
'AltaVista', |
|
784 |
'IDBot', |
|
785 |
'eStyle', |
|
786 |
'Scrubby', |
|
787 |
'gsa-crawler', |
|
788 |
); |
|
789 |
// Return on the first find. |
|
790 |
foreach ($crawlers as $c) { |
|
791 |
if (stripos($_SERVER['HTTP_USER_AGENT'], $c) !== FALSE) { |
|
792 |
return FALSE; |
|
784 |
if (isset($_SERVER['HTTP_USER_AGENT'])) { |
|
785 |
$crawlers = array( |
|
786 |
'Google', |
|
787 |
'msnbot', |
|
788 |
'Rambler', |
|
789 |
'Yahoo', |
|
790 |
'AbachoBOT', |
|
791 |
'accoona', |
|
792 |
'AcoiRobot', |
|
793 |
'ASPSeek', |
|
794 |
'CrocCrawler', |
|
795 |
'Dumbot', |
|
796 |
'FAST-WebCrawler', |
|
797 |
'GeonaBot', |
|
798 |
'Gigabot', |
|
799 |
'Lycos', |
|
800 |
'MSRBOT', |
|
801 |
'Scooter', |
|
802 |
'AltaVista', |
|
803 |
'IDBot', |
|
804 |
'eStyle', |
|
805 |
'Scrubby', |
|
806 |
'gsa-crawler', |
|
807 |
); |
|
808 |
// Return on the first find. |
|
809 |
foreach ($crawlers as $c) { |
|
810 |
if (stripos($_SERVER['HTTP_USER_AGENT'], $c) !== FALSE) { |
|
811 |
return FALSE; |
|
812 |
} |
|
793 | 813 |
} |
794 | 814 |
} |
795 | 815 |
|
... | ... | |
869 | 889 |
*/ |
870 | 890 |
function cas_form_alter(&$form, &$form_state, $form_id) { |
871 | 891 |
|
872 |
//drupal_set_message($form_id.'<pre>'.print_r($form,1).'</pre>'); |
|
873 | 892 |
switch ($form_id) { |
874 | 893 |
case 'user_login': |
875 | 894 |
case 'user_login_block': |
... | ... | |
953 | 972 |
} |
954 | 973 |
if (variable_get('cas_hide_password', 0)) { |
955 | 974 |
$form['account']['pass']['#access'] = FALSE; |
956 |
|
|
957 |
// Also remove requirement to validate your current password before |
|
958 |
// changing your e-mail address. |
|
959 |
$form['account']['current_pass']['#access'] = FALSE; |
|
960 |
$form['account']['current_pass_required_values']['#access'] = FALSE; |
|
961 |
$form['#validate'] = array_diff($form['#validate'], array('user_validate_current_pass')); |
|
962 | 975 |
} |
963 | 976 |
} |
977 |
if (cas_is_external_user($account) && variable_get('cas_hide_password', 0)) { |
|
978 |
// Also remove requirement to validate your current password before |
|
979 |
// changing your e-mail address. |
|
980 |
$form['account']['current_pass']['#access'] = FALSE; |
|
981 |
$form['account']['current_pass_required_values']['#access'] = FALSE; |
|
982 |
$form['account']['current_pass_required_values']['#value'] = array(); |
|
983 |
$form['#validate'] = array_diff($form['#validate'], array('user_validate_current_pass')); |
|
984 |
} |
|
964 | 985 |
break; |
965 | 986 |
|
966 | 987 |
case 'user_pass': |
... | ... | |
1046 | 1067 |
|
1047 | 1068 |
function _cas_single_sign_out_check() { |
1048 | 1069 |
if (isset($_POST["logoutRequest"])) { |
1049 |
$cas_logout_request_xml_string = utf8_encode($_POST["logoutRequest"]); // it's important!
|
|
1070 |
$cas_logout_request_xml_string = utf8_encode(urldecode($_POST["logoutRequest"]));
|
|
1050 | 1071 |
$cas_logout_request_xml = new SimpleXMLElement($cas_logout_request_xml_string); |
1051 | 1072 |
if (is_object($cas_logout_request_xml)) { |
1052 | 1073 |
$namespaces = $cas_logout_request_xml->getNameSpaces(); |
... | ... | |
1061 | 1082 |
// Log them out now. |
1062 | 1083 |
// first lets find out who we want to log off |
1063 | 1084 |
|
1064 |
$result = db_query_range("SELECT cld.uid FROM {cas_login_data} cld WHERE cld.cas_session_id = :ticket", 0 , 1, array(':ticket' => $cas_session_index)); |
|
1065 |
foreach ($result as $record) { |
|
1066 |
$uid = $record->uid; |
|
1067 |
$acct = user_load($uid); |
|
1068 |
watchdog('user', 'Session closed for %name.', array('%name' => $acct->name)); |
|
1069 |
// remove all entry for user id in cas_login_data |
|
1070 |
db_delete('cas_login_data') |
|
1071 |
->condition('uid', $uid) |
|
1072 |
->execute(); |
|
1073 |
|
|
1074 |
// remove their session |
|
1075 |
db_delete('sessions') |
|
1076 |
->condition('uid', $uid) |
|
1077 |
->execute(); |
|
1085 |
|
|
1086 |
$record = db_query_range("SELECT cld.uid, u.name FROM {users} u JOIN {cas_login_data} cld ON u.uid = cld.uid WHERE cld.cas_session_id = :ticket", 0, 1, array(':ticket' => $cas_session_index))->fetchObject(); |
|
1087 |
if ($record) { |
|
1088 |
watchdog('user', 'Session closed for %name by CAS logout request.', array('%name' => $record->name)); |
|
1089 |
//remove all entry for user id in cas_login_data |
|
1090 |
db_delete('cas_login_data') |
|
1091 |
->condition('uid', $record->uid) |
|
1092 |
->execute(); |
|
1093 |
|
|
1094 |
// remove their session |
|
1095 |
db_delete('sessions') |
|
1096 |
->condition('uid', $record->uid) |
|
1097 |
->execute(); |
|
1078 | 1098 |
} |
1079 | 1099 |
} |
1080 | 1100 |
} |
... | ... | |
1238 | 1258 |
* Get the CAS attributes of the current CAS user. |
1239 | 1259 |
* |
1240 | 1260 |
* Ensures that phpCAS is properly initialized before getting the attributes. |
1241 |
* @see phpCAS::getAttributes().
|
|
1261 |
* @see phpCAS::getAttributes() |
|
1242 | 1262 |
* |
1243 | 1263 |
* @param $cas_name |
1244 | 1264 |
* If provided, ensure that the currently logged in CAS user matches this |
drupal7/sites/all/modules/cas/cas.pages.inc | ||
---|---|---|
9 | 9 |
* Menu callback; Manage CAS identities for the specified user. |
10 | 10 |
*/ |
11 | 11 |
function cas_user_identities($account) { |
12 |
drupal_set_title(format_username($account));
|
|
12 |
drupal_set_title(check_plain(format_username($account)));
|
|
13 | 13 |
|
14 | 14 |
$header = array(t('CAS username'), t('Operations')); |
15 | 15 |
$rows = array(); |
drupal7/sites/all/modules/cas/cas.test | ||
---|---|---|
35 | 35 |
$this->admin_user = $this->drupalCreateUser(array('administer users', 'administer cas')); |
36 | 36 |
|
37 | 37 |
// Download and extract in PHPCAS. |
38 |
$this->downloadExtractPhpCas('1.2.2');
|
|
38 |
$this->downloadExtractPhpCas('1.3.1');
|
|
39 | 39 |
} |
40 | 40 |
|
41 | 41 |
/** |
... | ... | |
77 | 77 |
// Extract the files. |
78 | 78 |
$archiver = archiver_get_archiver($local_archive); |
79 | 79 |
$archiver->extract($simpletest_cache); |
80 |
// Work around issue https://issues.jasig.org/browse/PHPCAS-105. |
|
81 |
// @see http://drupal.org/node/1120034 |
|
82 |
switch ($version) { |
|
83 |
case '1.1.3': |
|
84 |
system_retrieve_file('http://drupal.org/files/issues/CAS-1.1.3-CAS-client.txt', $cas_library_dir . '/CAS/client.php', FALSE, FILE_EXISTS_REPLACE); |
|
85 |
break; |
|
86 |
case '1.2.1': |
|
87 |
system_retrieve_file('http://drupal.org/files/issues/CAS-1.2.1-CAS-client_0.txt', $cas_library_dir . '/CAS/client.php', FALSE, FILE_EXISTS_REPLACE); |
|
88 |
break; |
|
89 |
} |
|
90 | 80 |
} |
91 | 81 |
if (function_exists('sem_get')) { |
92 | 82 |
sem_release($semaphore); |
... | ... | |
145 | 135 |
} |
146 | 136 |
|
147 | 137 |
// Log in the user. |
148 |
$cas_name = is_object($account) ? $account->cas_name : $account; |
|
149 |
$cas_user = array('name' => $cas_name, 'attributes' => $attributes); |
|
150 |
variable_set('cas_test_cas_user', $cas_user); |
|
138 |
$cas_name = $this->setCasUser($account, $attributes); |
|
151 | 139 |
$this->drupalGet('cas'); |
152 | 140 |
|
153 | 141 |
$pass = $this->assertLink(t('Log out'), 0, t('CAS user %cas_name successfully logged in.', array('%cas_name' => $cas_name)), t('User login')); |
154 | 142 |
if ($pass) { |
155 |
$this->loggedInUser = cas_user_load_by_name($cas_name, TRUE); |
|
143 |
$this->loggedInUser = cas_user_load_by_name($cas_name, TRUE, TRUE);
|
|
156 | 144 |
} |
157 | 145 |
} |
158 | 146 |
|
147 |
/** |
|
148 |
* Set the CAS username and attributes for the next CAS login request. |
|
149 |
* |
|
150 |
* @param $account |
|
151 |
* A user object with a valid CAS username field, or the CAS username as a |
|
152 |
* string. |
|
153 |
* @param $attributes |
|
154 |
* Additional attributes for the CAS user. |
|
155 |
* |
|
156 |
* @return |
|
157 |
* The CAS username. |
|
158 |
*/ |
|
159 |
function setCasUser($account, $attributes = array()) { |
|
160 |
$cas_name = is_object($account) ? $account->cas_name : $account; |
|
161 |
$cas_user = array('name' => $cas_name, 'attributes' => $attributes); |
|
162 |
variable_set('cas_test_cas_user', $cas_user); |
|
163 |
return $cas_name; |
|
164 |
} |
|
165 |
|
|
166 |
/** |
|
167 |
* Clear the CAS username and attributes for the next CAS login request. |
|
168 |
*/ |
|
169 |
function clearCasUser() { |
|
170 |
variable_del('cas_test_cas_user'); |
|
171 |
} |
|
172 |
|
|
159 | 173 |
/** |
160 | 174 |
* Assert that the user has logged in. |
161 | 175 |
* |
... | ... | |
353 | 367 |
*/ |
354 | 368 |
function testCasAutoRegister() { |
355 | 369 |
$cas_name = $this->randomName(); |
356 |
variable_set('cas_test_cas_user', array('name' => $cas_name));
|
|
370 |
$this->setCasUser($cas_name);
|
|
357 | 371 |
|
358 | 372 |
// Test that the user is not automatically registered. |
359 | 373 |
variable_set('cas_user_register', FALSE); |
... | ... | |
370 | 384 |
// Create a new user. |
371 | 385 |
$user2 = $this->drupalCreateUser(); |
372 | 386 |
$cas_name = $user2->name; |
373 |
variable_set('cas_test_cas_user', array('name' => $cas_name));
|
|
387 |
$this->setCasUser($cas_name);
|
|
374 | 388 |
|
375 | 389 |
// Test that CAS does not hijack an existing username. |
376 | 390 |
$this->drupalGet('cas'); |
... | ... | |
423 | 437 |
|
424 | 438 |
$this->assertToken('[cas:name]', $account->cas_name); |
425 | 439 |
} |
440 |
|
|
441 |
function testCaseInsensitiveLogin() { |
|
442 |
$account = $this->casCreateUser(); |
|
443 |
$this->casLogin(strtoupper($account->cas_name)); |
|
444 |
$this->assertLoggedIn($account); |
|
445 |
} |
|
446 |
|
|
426 | 447 |
} |
427 | 448 |
|
428 | 449 |
/** |
... | ... | |
510 | 531 |
// Create a CAS user. |
511 | 532 |
$account = $this->casCreateUser(); |
512 | 533 |
$cas_name = $account->cas_name; |
513 |
variable_set('cas_test_cas_user', array('name' => $cas_name));
|
|
534 |
$this->setCasUser($cas_name);
|
|
514 | 535 |
|
515 | 536 |
// Test going to 'cas' |
516 | 537 |
$this->drupalGet('cas'); |
... | ... | |
572 | 593 |
variable_set('cas_first_login_destination', "node/$node->nid"); |
573 | 594 |
$cas_name = $this->randomName(); |
574 | 595 |
$account = $this->casLogin($cas_name); |
575 |
$this->assertUrl("node/$node->nid"); |
|
596 |
$this->assertUrl("node/$node->nid", array('query' => array('destination' => '')));
|
|
576 | 597 |
$this->drupalLogout(); |
577 | 598 |
|
578 | 599 |
// The second login should not be redirected. |
... | ... | |
584 | 605 |
// destination. |
585 | 606 |
$account = $this->casCreateUser(); |
586 | 607 |
$this->casLogin($account); |
587 |
$this->assertUrl("node/$node->nid"); |
|
608 |
$this->assertUrl("node/$node->nid", array('query' => array('destination' => '')));
|
|
588 | 609 |
$this->drupalLogout(); |
589 | 610 |
|
590 | 611 |
// The second login should not be redirected. |
... | ... | |
619 | 640 |
// @todo: Add additional tests for other methods of logging in (especially |
620 | 641 |
// methods coming from cas_pages). |
621 | 642 |
} |
643 |
|
|
644 |
function testSingleSignOutDoubleEncode() { |
|
645 |
// Create a user, and log in. |
|
646 |
$cas_name = $this->randomName(); |
|
647 |
$account = $this->casCreateUser($cas_name); |
|
648 |
$this->casLogin($account); |
|
649 |
|
|
650 |
cas_test_single_sign_out($cas_name, TRUE); |
|
651 |
$this->assertLoggedOut(); |
|
652 |
|
|
653 |
// @todo: Add additional tests for other methods of logging in (especially |
|
654 |
// methods coming from cas_pages). |
|
655 |
} |
|
622 | 656 |
} |
623 | 657 |
|
624 | 658 |
/** |
... | ... | |
658 | 692 |
// Create a user. |
659 | 693 |
$cas_name = $this->randomName(); |
660 | 694 |
$account = $this->casCreateUser($cas_name); |
661 |
variable_set('cas_test_cas_user', array('name' => $cas_name));
|
|
695 |
$this->setCasUser($cas_name);
|
|
662 | 696 |
|
663 | 697 |
$this->drupalGet('node'); |
664 | 698 |
$this->assertLoggedIn($account); |
... | ... | |
685 | 719 |
$node1 = $this->drupalCreateNode(); |
686 | 720 |
$node2 = $this->drupalCreateNode(); |
687 | 721 |
$account = $this->casCreateUser(); |
688 |
variable_set('cas_test_cas_user', array('name' => $account->cas_name));
|
|
722 |
$this->setCasUser($account);
|
|
689 | 723 |
|
690 | 724 |
$this->drupalGet("node/$node2->nid"); |
691 | 725 |
|
... | ... | |
707 | 741 |
$this->assertField('pass', t('Password field found.'), t('Logout')); |
708 | 742 |
|
709 | 743 |
// Verify that accessing any other page redirects to the login page. |
710 |
variable_del('cas_test_cas_user');
|
|
744 |
$this->clearCasUser();
|
|
711 | 745 |
$this->drupalGet('node'); |
712 | 746 |
$this->assertText('No CAS name provided.'); |
713 | 747 |
} |
... | ... | |
718 | 752 |
function testCasExclude() { |
719 | 753 |
$node = $this->drupalCreateNode(); |
720 | 754 |
$account = $this->casCreateUser(); |
721 |
variable_set('cas_test_cas_user', array('name' => $account->cas_name));
|
|
755 |
$this->setCasUser($account);
|
|
722 | 756 |
|
723 | 757 |
variable_set('cas_check_first', TRUE); |
724 | 758 |
variable_set('cas_exclude', "node/$node->nid"); |
... | ... | |
786 | 820 |
*/ |
787 | 821 |
function testCasLoginBlock() { |
788 | 822 |
$account = $this->casCreateUser(); |
789 |
variable_set('cas_test_cas_user', array('name' => $account->cas_name));
|
|
823 |
$this->setCasUser($account);
|
|
790 | 824 |
|
791 | 825 |
// Verify that the block is shown on some pages, but not on others. |
792 | 826 |
$this->drupalGet(''); |
drupal7/sites/all/modules/cas/cas.user.inc | ||
---|---|---|
16 | 16 |
'#title' => t('CAS username'), |
17 | 17 |
'#required' => TRUE, |
18 | 18 |
'#default_value' => '', |
19 |
'#description' => t('Registration will proceded as if the user with the specified CAS username just logged in.'),
|
|
19 |
'#description' => t('Registration will proceed as if the user with the specified CAS username just logged in.'), |
|
20 | 20 |
'#element_validate' => array('_cas_name_element_validate'), |
21 | 21 |
'#weight' => -10, |
22 | 22 |
); |
drupal7/sites/all/modules/cas/cas_server.api.php | ||
---|---|---|
33 | 33 |
$attributes['friends'] = array('dries', 'webchick'); |
34 | 34 |
|
35 | 35 |
// Or change the response based upon the server. |
36 |
if (preg_match($service, "@^http://apple.com/@")) {
|
|
36 |
if (preg_match("@^http://apple.com/@", $service)) {
|
|
37 | 37 |
// This data should not be confidential as the service URL is directly |
38 | 38 |
// supplied by the user and is in no way validated. |
39 | 39 |
$attributes['friends'] += 'sjobs'; |
drupal7/sites/all/modules/cas/cas_server.info | ||
---|---|---|
3 | 3 |
core = 7.x |
4 | 4 |
description = "Provides protocol compliant CAS Server" |
5 | 5 |
|
6 |
; Information added by drupal.org packaging script on 2012-05-09
|
|
7 |
version = "7.x-1.2"
|
|
6 |
; Information added by Drupal.org packaging script on 2014-04-02
|
|
7 |
version = "7.x-1.3"
|
|
8 | 8 |
core = "7.x" |
9 | 9 |
project = "cas" |
10 |
datestamp = "1336595150"
|
|
10 |
datestamp = "1396458247"
|
|
11 | 11 |
|
drupal7/sites/all/modules/cas/cas_server.install | ||
---|---|---|
35 | 35 |
'type' => 'int', |
36 | 36 |
'not null' => TRUE, |
37 | 37 |
), |
38 |
'valid' => array( |
|
39 |
'type' => 'int', |
|
40 |
'not null' => TRUE, |
|
41 |
'default' => 1, |
|
42 |
), |
|
38 | 43 |
), |
39 | 44 |
'primary key' => array('ticket'), |
40 | 45 |
); |
... | ... | |
46 | 51 |
/** |
47 | 52 |
* Creates CAS server tickets table. |
48 | 53 |
*/ |
49 |
function cas_server_update_1() {
|
|
54 |
function cas_server_update_7000() {
|
|
50 | 55 |
$schema = array(); |
51 | 56 |
|
52 | 57 |
$schema['cas_server_tickets'] = array( |
... | ... | |
78 | 83 |
); |
79 | 84 |
|
80 | 85 |
$ret = array(); |
81 |
db_create_table($ret, 'cas_server_tickets', $schema['cas_server_tickets']);
|
|
86 |
db_create_table('cas_server_tickets', $schema['cas_server_tickets']); |
|
82 | 87 |
return $ret; |
83 | 88 |
} |
89 |
|
|
90 |
/** |
|
91 |
* Adds valid field to indicate when ticket is valid for reuse. |
|
92 |
*/ |
|
93 |
function cas_server_update_7101() { |
|
94 |
db_add_field('cas_server_tickets', 'valid', array('type' => 'int', 'not null' => TRUE, 'default' => 1, )); |
|
95 |
} |
drupal7/sites/all/modules/cas/cas_server.module | ||
---|---|---|
64 | 64 |
'variables' => array('ticket' => NULL, 'error_code' => NULL), |
65 | 65 |
'file' => 'cas_server.response.inc', |
66 | 66 |
), |
67 |
'cas_service_logout_request' => array( |
|
68 |
'variables' => array('ticket' => NULL, 'date' => NULL, 'id' => NULL), |
|
69 |
'file' => 'cas_server.response.inc', |
|
70 |
), |
|
67 | 71 |
); |
68 | 72 |
} |
69 | 73 |
|
... | ... | |
131 | 135 |
* This provides the simple non-xml based |
132 | 136 |
*/ |
133 | 137 |
function cas_server_validate() { |
138 |
// Prevent this page from being cached. |
|
139 |
drupal_page_is_cacheable(FALSE); |
|
140 |
|
|
141 |
// Set content type. |
|
142 |
drupal_add_http_header('Content-Type', 'text/plain; charset=utf-8'); |
|
143 |
|
|
134 | 144 |
//Obtain the ticket from the url and validate it. |
135 | 145 |
$ticket = isset($_REQUEST['ticket']) ? $_REQUEST['ticket'] : ''; |
136 | 146 |
$service = isset($_REQUEST['service']) ? $_REQUEST['service'] : ''; |
... | ... | |
149 | 159 |
* Returns data in xml |
150 | 160 |
*/ |
151 | 161 |
function cas_server_service_validate() { |
162 |
// Prevent this page from being cached. |
|
163 |
drupal_page_is_cacheable(FALSE); |
|
164 |
|
|
165 |
// Set content type. |
|
166 |
drupal_add_http_header('Content-Type', 'text/xml; charset=utf-8'); |
|
167 |
|
|
152 | 168 |
$ticket = isset($_REQUEST['ticket']) ? $_REQUEST['ticket'] : ''; |
153 | 169 |
$service = isset($_REQUEST['service']) ? $_REQUEST['service'] : ''; |
154 | 170 |
$user_name = _cas_server_validate($service, $ticket); |
155 | 171 |
if (!$user_name) $cas_error='INVALID_TICKET'; |
156 | 172 |
if (!$ticket || !$service) $cas_error='INVALID_REQUEST'; |
157 | 173 |
|
158 |
header('Content-type:', 'text/xml'); |
|
159 | 174 |
if ($user_name) { |
160 | 175 |
//@TODO Generate proxy granting ticket |
161 | 176 |
$account = user_load_by_name($user_name); |
... | ... | |
189 | 204 |
// Look up the ticket |
190 | 205 |
$user_name=''; |
191 | 206 |
$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); |
|
207 |
$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 AND valid=1", 0, 1, $ticket_info);
|
|
193 | 208 |
if ($result !== FALSE) { |
194 | 209 |
foreach ($result as $ticket_data) { |
195 | 210 |
$user_name = $ticket_data->name; |
196 | 211 |
} |
197 | 212 |
} |
198 |
db_delete('cas_server_tickets') |
|
213 |
db_update('cas_server_tickets') |
|
214 |
->fields(array('valid' => 0)) |
|
199 | 215 |
->condition('ticket', $ticket) |
200 | 216 |
->execute(); |
201 | 217 |
|
... | ... | |
211 | 227 |
// Generate the ticket |
212 | 228 |
$time = REQUEST_TIME; |
213 | 229 |
$ticket = 'ST-' . user_password(); |
214 |
$ticket_data = array('uid' => $uid, 'service' => $service, 'ticket' => $ticket, 'timestamp' => $time); |
|
230 |
$ticket_data = array('uid' => $uid, 'service' => $service, 'ticket' => $ticket, 'timestamp' => $time, 'valid' => 1);
|
|
215 | 231 |
// Save the ticket to the db |
216 | 232 |
if ($uid && $service) { |
217 | 233 |
db_insert('cas_server_tickets')->fields($ticket_data)->execute(); |
... | ... | |
221 | 237 |
|
222 | 238 |
/** |
223 | 239 |
* Menu callback; triggers a CAS logout. |
224 |
* |
|
225 |
* @TODO: Implement single sign out support |
|
226 | 240 |
*/ |
227 | 241 |
function cas_server_logout() { |
228 | 242 |
global $user; |
... | ... | |
240 | 254 |
} |
241 | 255 |
return $output; |
242 | 256 |
} |
257 |
|
|
258 |
/** |
|
259 |
* Send CAS a logout requests for each of the user's CAS tickets. |
|
260 |
* |
|
261 |
* @param $account |
|
262 |
* The user for whom to send CAS logout requests. |
|
263 |
*/ |
|
264 |
function cas_server_logout_clients($account) { |
|
265 |
$result = db_query("SELECT service, ticket, valid FROM {cas_server_tickets} WHERE uid= :uid", array(':uid' => $account->uid)); |
|
266 |
if ($result !== FALSE) { |
|
267 |
$expired_tickets = array(); |
|
268 |
foreach ($result as $client) { |
|
269 |
$expired_tickets[] = $client->ticket; |
|
270 |
if (!$client->valid) { |
|
271 |
$id = 'LR-' . user_password(); |
|
272 |
$date = date('c'); |
|
273 |
$logout_request = theme('cas_service_logout_request', array('id' => $id, 'date' => $date, 'ticket' => $client->ticket)); |
|
274 |
// Send POST request |
|
275 |
$response = drupal_http_request( |
|
276 |
$client->service, |
|
277 |
array( |
|
278 |
'headers' => array('Content-Type' => 'application/x-www-form-urlencoded'), |
|
279 |
'method' => 'POST', |
|
280 |
'data' => 'logoutRequest=' . urlencode($logout_request), |
|
281 |
) |
|
282 |
); |
|
283 |
if (@$response->error) { |
|
284 |
watchdog('error', 'Error in CAS logout Request - %code : %message', array('%code' => $response->code, '%error' => $response->error)); |
|
285 |
} |
|
286 |
} |
|
287 |
// Remove ticket |
|
288 |
} |
|
289 |
if ($expired_tickets) { |
|
290 |
db_delete('cas_server_tickets') |
|
291 |
->condition('ticket', $expired_tickets, 'IN') |
|
292 |
->execute(); |
|
293 |
} |
|
294 |
} |
|
295 |
} |
|
296 |
|
|
297 |
/** |
|
298 |
* Implements hook_user_logout(). |
|
299 |
*/ |
|
300 |
function cas_server_user_logout($account) { |
|
301 |
cas_server_logout_clients($account); |
|
302 |
} |
drupal7/sites/all/modules/cas/cas_server.response.inc | ||
---|---|---|
15 | 15 |
*/ |
16 | 16 |
function theme_cas_service_validate_success($variables) { |
17 | 17 |
$cas_name = $variables['name']; |
18 |
$output .= "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>\n";
|
|
18 |
$output = "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>\n"; |
|
19 | 19 |
$output .= "<cas:authenticationSuccess>\n"; |
20 | 20 |
$output .= "<cas:user>$cas_name</cas:user>\n"; |
21 | 21 |
$output .= theme('cas_service_validate_attributes', $variables); |
... | ... | |
40 | 40 |
$style = $variables['style']; |
41 | 41 |
|
42 | 42 |
$output = ''; |
43 |
switch($style) { |
|
43 |
switch ($style) {
|
|
44 | 44 |
case 'jasig': |
45 | 45 |
default: |
46 | 46 |
$output .= "<cas:attributes>\n"; |
... | ... | |
91 | 91 |
|
92 | 92 |
return $output; |
93 | 93 |
} |
94 |
|
|
95 |
|
|
96 |
/** |
|
97 |
* Generate the Single Sign Out request. |
|
98 |
* |
|
99 |
* @param unknown_type $variables |
|
100 |
* An associative array containing the key, date and logout id request |
|
101 |
*/ |
|
102 |
function theme_cas_service_logout_request($variables) { |
|
103 |
$id = $variables['id']; |
|
104 |
$date = $variables['date']; |
|
105 |
$ticket = $variables['ticket']; |
|
106 |
$output = "<samlp:LogoutRequest xmlns:samlp='urn:oasis:names:tc:SAML:2.0:protocol' ID='$id' Version='2.0' IssueInstant='$date'>\n"; |
|
107 |
$output .= "<saml:NameID xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>@NOT_USED@</saml:NameID>\n"; |
|
108 |
$output .= "<samlp:SessionIndex>$ticket</samlp:SessionIndex>\n"; |
|
109 |
$output .= "</samlp:LogoutRequest>\n"; |
|
110 |
return $output; |
|
111 |
} |
drupal7/sites/all/modules/cas/includes/views/handlers/cas_handler_field_cas_name.inc | ||
---|---|---|
1 | 1 |
<?php |
2 |
|
|
3 |
/** |
|
4 |
* @file |
|
5 |
* Field handler to provide a list of CAS user names. |
|
6 |
*/ |
|
7 |
|
|
2 | 8 |
/** |
3 | 9 |
* Field handler to provide a list of CAS user names. |
4 | 10 |
*/ |
drupal7/sites/all/modules/cas/tests/cas_test.info | ||
---|---|---|
8 | 8 |
; code duplication we use several themes defined by that module. |
9 | 9 |
dependencies[] = cas_server |
10 | 10 |
|
11 |
; Information added by drupal.org packaging script on 2012-05-09
|
|
12 |
version = "7.x-1.2"
|
|
11 |
; Information added by Drupal.org packaging script on 2014-04-02
|
|
12 |
version = "7.x-1.3"
|
|
13 | 13 |
core = "7.x" |
14 | 14 |
project = "cas" |
15 |
datestamp = "1336595150"
|
|
15 |
datestamp = "1396458247"
|
|
16 | 16 |
|
drupal7/sites/all/modules/cas/tests/cas_test.module | ||
---|---|---|
103 | 103 |
|
104 | 104 |
if ($cas_user) { |
105 | 105 |
if (!is_array($cas_user)) { |
106 |
$cas_user = array('name' => $cas_user); |
|
106 |
$cas_user = array('name' => $cas_user, 'attributes' => array());
|
|
107 | 107 |
} |
108 | 108 |
// Generate a ticket and redirect to the service URL with the login ticket. |
109 | 109 |
$ticket = _cas_test_ticket_generate($service, $cas_user); |
... | ... | |
128 | 128 |
* Validate a ticket using the CAS 1.x protocol. |
129 | 129 |
*/ |
130 | 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 |
|
|
131 | 137 |
//Obtain the ticket from the url and validate it. |
132 | 138 |
$ticket = $_GET['ticket']; |
133 | 139 |
$service = $_GET['service']; |
... | ... | |
148 | 154 |
* Validate a ticket using the CAS 2.0 protocol. |
149 | 155 |
*/ |
150 | 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 |
|
|
151 | 163 |
$ticket = $_GET['ticket']; |
152 | 164 |
$service = $_GET['service']; |
153 | 165 |
|
154 |
header('Content-type:', 'text/xml'); |
|
155 | 166 |
if ($cas_user = _cas_test_ticket_validate($service, $ticket)) { |
156 | 167 |
print theme('cas_service_validate_success', $cas_user); |
157 | 168 |
} |
... | ... | |
234 | 245 |
* |
235 | 246 |
* @param $cas_user |
236 | 247 |
*/ |
237 |
function cas_test_single_sign_out($cas_name) { |
|
248 |
function cas_test_single_sign_out($cas_name, $double_encode=FALSE) {
|
|
238 | 249 |
$sso = variable_get('cas_test_sso', array()); |
239 | 250 |
foreach ($sso[$cas_name] as $service => $tickets) { |
240 | 251 |
foreach ($tickets as $ticket) { |
... | ... | |
243 | 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)), |
244 | 255 |
); |
245 | 256 |
|
257 |
if ($double_encode) { |
|
258 |
// Certain CAS servers urlencode the logoutRequest. |
|
259 |
$data['logoutRequest'] = urlencode($data['logoutRequest']); |
|
260 |
} |
|
261 |
|
|
246 | 262 |
// Sign out the user. |
247 | 263 |
$options = array( |
248 | 264 |
'method' => 'POST', |
drupal7/sites/all/modules/print/print.info | ||
---|---|---|
1 | 1 |
name = "Printer-friendly pages" |
2 |
description = "Adds a printer-friendly version link to content and administrative pages."
|
|
3 |
core=7.x
|
|
2 |
description = "Generates a printer-friendly version of Drupal pages."
|
|
3 |
core = 7.x
|
|
4 | 4 |
package = "Printer, email and PDF versions" |
5 |
files[] = print.module |
|
6 |
files[] = print.admin.inc |
|
7 |
files[] = print.pages.inc |
|
8 |
files[] = print.install |
|
9 |
files[] = print.views.inc |
|
10 | 5 |
files[] = print_join_page_counter.inc |
6 |
dependencies[] = node |
|
11 | 7 |
configure = admin/config/user-interface/print |
12 | 8 |
|
13 |
; Information added by drupal.org packaging script on 2012-09-04
|
|
14 |
version = "7.x-1.2"
|
|
9 |
; Information added by Drupal.org packaging script on 2014-04-02
|
|
10 |
version = "7.x-1.3"
|
|
15 | 11 |
core = "7.x" |
16 | 12 |
project = "print" |
17 |
datestamp = "1346768900"
|
|
13 |
datestamp = "1396426750"
|
|
18 | 14 |
|
drupal7/sites/all/modules/print/print.install | ||
---|---|---|
126 | 126 |
'fields' => array( |
127 | 127 |
'path' => array( |
128 | 128 |
'type' => 'varchar', |
129 |
'length' => 128,
|
|
129 |
'length' => 255,
|
|
130 | 130 |
'not null' => TRUE, |
131 | 131 |
'description' => 'Page path', |
132 | 132 |
), |
... | ... | |
175 | 175 |
$link_pos['help'] = 'help'; |
176 | 176 |
variable_set('print_html_link_pos', $link_pos); |
177 | 177 |
} |
178 |
|
|
179 |
/** |
|
180 |
* Increase size of the path field in the print_page_counter table |
|
181 |
*/ |
|
182 |
function print_update_7103(&$sandbox) { |
|
183 |
db_drop_primary_key('print_page_counter'); |
|
184 |
db_change_field('print_page_counter', 'path', 'path', |
|
185 |
array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'description' => 'Page path'), |
|
186 |
array('primary key' => array('path'))); |
|
187 |
} |
drupal7/sites/all/modules/print/print.module | ||
---|---|---|
263 | 263 |
* Implements hook_block_view(). |
264 | 264 |
*/ |
265 | 265 |
function print_block_view($delta = '') { |
266 |
$block = array(); |
|
267 |
|
|
266 | 268 |
switch ($delta) { |
267 | 269 |
case 'print-links': |
268 | 270 |
$nid = preg_replace('!^node/!', '', $_GET['q']); |
... | ... | |
465 | 467 |
*/ |
466 | 468 |
function print_node_update($node) { |
467 | 469 |
if (user_access('administer print') || user_access('node-specific print configuration')) { |
468 |
if (!isset($node->print_display)) $node->print_display = variable_get('print_display_' . $node->type, PRINT_TYPE_SHOW_LINK_DEFAULT); |
|
469 |
if (!isset($node->print_display_comment)) $node->print_display_comment = variable_get('print_display_comment_' . $node->type, PRINT_TYPE_COMMENT_LINK_DEFAULT); |
|
470 |
if (!isset($node->print_display_urllist)) $node->print_display_urllist = variable_get('print_display_urllist_' . $node->type, PRINT_TYPE_URLLIST_DEFAULT); |
|
470 |
if (!isset($node->print_display) || $node->print_display === NULL) { |
|
471 |
$node->print_display = variable_get('print_display_' . $node->type, PRINT_TYPE_SHOW_LINK_DEFAULT); |
|
472 |
} |
|
473 |
if (!isset($node->print_display_comment) || $node->print_display_comment === NULL) { |
|
474 |
$node->print_display_comment = variable_get('print_display_comment_' . $node->type, PRINT_TYPE_COMMENT_LINK_DEFAULT); |
|
475 |
} |
|
476 |
if (!isset($node->print_display_urllist) || $node->print_display_urllist === NULL) { |
|
477 |
$node->print_display_urllist = variable_get('print_display_urllist_' . $node->type, PRINT_TYPE_URLLIST_DEFAULT); |
|
478 |
} |
|
471 | 479 |
|
472 | 480 |
_print_node_conf_modify($node->nid, $node->print_display, $node->print_display_comment, $node->print_display_urllist); |
473 | 481 |
} |
drupal7/sites/all/modules/print/print.pages.inc | ||
---|---|---|
193 | 193 |
$print['favicon'] = theme_get_setting('toggle_favicon') ? "<link rel='shortcut icon' href='" . theme_get_setting('favicon') . "' type='image/x-icon' />\n" : ''; |
194 | 194 |
|
195 | 195 |
if (!empty($print_css)) { |
196 |
drupal_add_css(strtr($print_css, array('%t' => path_to_theme())));
|
|
196 |
drupal_add_css(strtr($print_css, array('%t' => drupal_get_path('theme', variable_get('theme_default')))));
|
|
197 | 197 |
} |
198 | 198 |
else { |
199 | 199 |
drupal_add_css(drupal_get_path('module', 'print') . '/css/print.css'); |
... | ... | |
254 | 254 |
$footer = $print_footer_user; |
255 | 255 |
break; |
256 | 256 |
} |
257 |
// Delete the contextual links |
|
258 |
$footer = preg_replace('!\s*<div class="contextual-links-wrapper">.*?</div>!sim', '', $footer); |
|
259 |
|
|
257 | 260 |
$print['footer_message'] = filter_xss_admin($footer); |
258 | 261 |
|
259 | 262 |
$published_site = variable_get('site_name', 0); |
... | ... | |
387 | 390 |
} |
388 | 391 |
// Because base href is the original page, change the link to |
389 | 392 |
// still be usable inside the print page |
390 |
$matches[1] = str_replace($url, base_path() . $_GET['q'] . $url, $matches[1]);
|
|
393 |
$matches[1] = str_replace($url, check_plain(base_path() . $_GET['q'] . $url), $matches[1]);
|
|
391 | 394 |
} |
392 | 395 |
else { |
393 | 396 |
// URL is relative, convert it into absolute URL |
... | ... | |
416 | 419 |
} |
417 | 420 |
} |
418 | 421 |
|
419 |
return $ret;
|
|
422 |
return filter_xss_admin($ret);
|
|
420 | 423 |
} |
421 | 424 |
|
422 | 425 |
/** |
... | ... | |
671 | 674 |
// Delete any links area |
672 | 675 |
$node->body = preg_replace('!\s*<div class="links">.*?</div>!sim', '', $node->body); |
673 | 676 |
|
677 |
// Delete the contextual links also |
|
678 |
$node->content = preg_replace('!\s*<div class="contextual-links-wrapper">.*?</div>!sim', '', $node->content); |
|
679 |
|
|
674 | 680 |
// Check URL list settings |
675 | 681 |
$_print_urls = _print_url_list_enabled($node, $format); |
676 | 682 |
|
drupal7/sites/all/modules/print/print_join_page_counter.inc | ||
---|---|---|
11 | 11 |
// PHP 4 doesn't call constructors of the base class automatically from a |
12 | 12 |
// constructor of a derived class. It is your responsibility to propagate |
13 | 13 |
// the call to constructors upstream where appropriate. |
14 |
function construct($table, $left_table, $left_field, $field, $extra = array(), $type = 'LEFT') {
|
|
14 |
function construct($table = NULL, $left_table = NULL, $left_field = NULL, $field = NULL, $extra = array(), $type = 'LEFT') {
|
|
15 | 15 |
parent::construct($table, $left_table, $left_field, $field, $extra, $type); |
16 | 16 |
} |
17 | 17 |
|
18 | 18 |
function build_join($select_query, $table, $view_query) { |
19 |
$this->left_field = "CONCAT('node/', " . $this->left_table . '.' . $this->left_field . ')'; |
|
20 |
$this->left_table = NULL; |
|
19 |
if ($this->left_table) { |
|
20 |
$this->left_field = "CONCAT('node/', $this->left_table.$this->left_field)"; |
|
21 |
$this->left_table = NULL; |
|
22 |
} |
|
21 | 23 |
parent::build_join($select_query, $table, $view_query); |
22 | 24 |
} |
23 | 25 |
} |
drupal7/sites/all/modules/print/print_mail/print_mail.inc | ||
---|---|---|
116 | 116 |
'#required' => TRUE, |
117 | 117 |
); |
118 | 118 |
if (!empty($title)) { |
119 |
// To prevent useless translation strings, try to translate only node titles |
|
120 |
if (drupal_substr($path, 0, 5) == 'node/') {
|
|
119 |
// To prevent useless translation strings, try to translate only non-node titles
|
|
120 |
if (drupal_substr($path, 0, 5) != 'node/') {
|
|
121 | 121 |
$title = t($title); |
122 | 122 |
} |
123 | 123 |
|
... | ... | |
150 | 150 |
'#type' => 'submit', |
151 | 151 |
'#value' => t('Send email'), |
152 | 152 |
); |
153 |
$form['btn_clear'] = array( |
|
154 |
'#type' => 'markup', |
|
155 |
'#markup' => '<input type="reset" name="clear" id="edit-btn-clear" value="' . t('Clear form') . '" class="form-submit" />', |
|
156 |
); |
|
157 | 153 |
$form['btn_cancel'] = array( |
158 | 154 |
'#name' => 'cancel', |
159 | 155 |
'#type' => 'submit', |
drupal7/sites/all/modules/print/print_mail/print_mail.info | ||
---|---|---|
1 | 1 |
name = "Send by email" |
2 | 2 |
description = "Provides the capability to send the web page by email" |
3 |
core=7.x
|
|
3 |
core = 7.x
|
|
4 | 4 |
package = "Printer, email and PDF versions" |
5 | 5 |
dependencies[] = print |
6 |
files[] = print_mail.module |
|
7 |
files[] = print_mail.inc |
|
8 |
files[] = print_mail.admin.inc |
|
9 |
files[] = print_mail.install |
|
10 |
files[] = print_mail.views.inc |
|
11 | 6 |
configure = admin/config/user-interface/print/email |
12 | 7 |
|
13 |
; Information added by drupal.org packaging script on 2012-09-04
|
|
14 |
version = "7.x-1.2"
|
|
8 |
; Information added by Drupal.org packaging script on 2014-04-02
|
|
9 |
version = "7.x-1.3"
|
|
15 | 10 |
core = "7.x" |
16 | 11 |
project = "print" |
17 |
datestamp = "1346768900"
|
|
12 |
datestamp = "1396426750"
|
|
18 | 13 |
|
drupal7/sites/all/modules/print/print_mail/print_mail.install | ||
---|---|---|
115 | 115 |
'fields' => array( |
116 | 116 |
'path' => array( |
117 | 117 |
'type' => 'varchar', |
118 |
'length' => 128,
|
|
118 |
'length' => 255,
|
|
119 | 119 |
'not null' => TRUE, |
120 | 120 |
'description' => 'Page path', |
121 | 121 |
), |
... | ... | |
201 | 201 |
$link_pos['help'] = 'help'; |
202 | 202 |
variable_set('print_mail_link_pos', $link_pos); |
203 | 203 |
} |
204 |
|
|
205 |
/** |
|
206 |
* Increase size of the path field in the print_mail_page_counter table |
|
207 |
*/ |
|
208 |
function print_mail_update_7103(&$sandbox) { |
|
209 |
db_drop_primary_key('print_mail_page_counter'); |
|
210 |
db_change_field('print_mail_page_counter', 'path', 'path', |
|
211 |
array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'description' => 'Page path'), |
|
212 |
array('primary key' => array('path'))); |
|
213 |
} |
drupal7/sites/all/modules/print/print_mail/print_mail.module | ||
---|---|---|
145 | 145 |
* Implements hook_block_view(). |
146 | 146 |
*/ |
147 | 147 |
function print_mail_block_view($delta = 0) { |
148 |
$block = array(); |
|
149 |
|
|
148 | 150 |
switch ($delta) { |
149 | 151 |
case 'print_mail-top': |
150 | 152 |
$block['subject'] = t('Most emailed'); |
... | ... | |
278 | 280 |
*/ |
279 | 281 |
function print_mail_node_update($node) { |
280 | 282 |
if (user_access('administer print') || user_access('node-specific print configuration')) { |
281 |
if (!isset($node->print_mail_display)) $node->print_mail_display = variable_get('print_mail_display_' . $node->type, PRINT_TYPE_SHOW_LINK_DEFAULT); |
|
282 |
if (!isset($node->print_mail_display_comment)) $node->print_mail_display_comment = variable_get('print_mail_display_comment_' . $node->type, PRINT_TYPE_COMMENT_LINK_DEFAULT); |
|
283 |
if (!isset($node->print_mail_display_urllist)) $node->print_mail_display_urllist = variable_get('print_mail_display_urllist_' . $node->type, PRINT_TYPE_URLLIST_DEFAULT); |
|
283 |
if (!isset($node->print_mail_display) || $node->print_mail_display === NULL) { |
|
284 |
$node->print_mail_display = variable_get('print_mail_display_' . $node->type, PRINT_TYPE_SHOW_LINK_DEFAULT); |
|
285 |
} |
|
286 |
if (!isset($node->print_mail_display_comment) || $node->print_mail_display_comment === NULL) { |
|
287 |
$node->print_mail_display_comment = variable_get('print_mail_display_comment_' . $node->type, PRINT_TYPE_COMMENT_LINK_DEFAULT); |
|
288 |
} |
|
289 |
if (!isset($node->print_mail_display_urllist) || $node->print_mail_display_urllist === NULL) { |
|
290 |
$node->print_mail_display_urllist = variable_get('print_mail_display_urllist_' . $node->type, PRINT_TYPE_URLLIST_DEFAULT); |
|
291 |
} |
|
284 | 292 |
|
285 | 293 |
_print_mail_node_conf_modify($node->nid, $node->print_mail_display, $node->print_mail_display_comment, $node->print_mail_display_urllist); |
286 | 294 |
} |
drupal7/sites/all/modules/print/print_pdf/print_pdf.admin.inc | ||
---|---|---|
260 | 260 |
else { |
261 | 261 |
$form['settings'] = array( |
262 | 262 |
'#type' => 'markup', |
263 |
'#markup' => '<p>' . t("No PDF generation tool found! Please dowload a supported PHP PDF generation tool. Check this module's INSTALL.txt for more details.") . '</p>', |
|
263 |
'#markup' => '<p>' . t("No PDF generation tool found! Please download a supported PHP PDF generation tool. Check this module's INSTALL.txt for more details.") . '</p>',
|
|
264 | 264 |
); |
265 | 265 |
} |
266 | 266 |
|
drupal7/sites/all/modules/print/print_pdf/print_pdf.class.inc | ||
---|---|---|
12 | 12 |
class PrintTCPDF extends TCPDF { |
13 | 13 |
public $footer; |
14 | 14 |
|
15 |
// Display invisible link at the bottom of all pages. |
|
16 |
public function setTcpdfLink($tcpdflink) { |
|
17 |
$this->tcpdflink = $tcpdflink; |
|
18 |
} |
|
19 |
|
|
15 | 20 |
// Page footer data |
16 |
public function SetFooterData($arg = '') {
|
|
21 |
public function setFooterContent($arg = '') {
|
|
17 | 22 |
$this->footer = $arg; |
18 | 23 |
} |
19 | 24 |
|
drupal7/sites/all/modules/print/print_pdf/print_pdf.drush.inc | ||
---|---|---|
13 | 13 |
define('TCPDF_DOWNLOAD_URI', 'http://sourceforge.net/projects/tcpdf/files/latest'); |
14 | 14 |
|
15 | 15 |
// URI to the the latest dompdf version.. Hardcoded version unfortunately |
16 |
define('DOMPDF_DOWNLOAD_URI', 'http://dompdf.googlecode.com/files/dompdf_0-6-0_beta3.tar.gz');
|
|
16 |
define('DOMPDF_DOWNLOAD_URI', 'https://github.com/dompdf/dompdf/releases/download/v0.6.1/dompdf-0.6.1.zip');
|
|
17 | 17 |
|
18 | 18 |
// wkhtmltopdf is a binary, requiring a different download for each platform |
19 |
define('WKHTMLTOPDF_AMD64_DOWNLOAD_URI', 'http://wkhtmltopdf.googlecode.com/files/wkhtmltopdf-0.11.0_rc1-static-amd64.tar.bz2'); |
|
20 |
define('WKHTMLTOPDF_I386_DOWNLOAD_URI', 'http://wkhtmltopdf.googlecode.com/files/wkhtmltopdf-0.11.0_rc1-static-i386.tar.bz2'); |
|
21 |
define('WKHTMLTOPDF_WIN_DOWNLOAD_URI', 'http://wkhtmltopdf.googlecode.com/files/wkhtmltox-0.11.0_rc1-installer.exe'); |
|
19 |
define('WKHTMLTOPDF_AMD64_DOWNLOAD_URI', 'http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.0/wkhtmltox-linux-amd64_0.12.0-03c001d.tar.xz'); |
|
20 |
define('WKHTMLTOPDF_I386_DOWNLOAD_URI', 'http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.0/wkhtmltox-linux-i386_0.12.0-03c001d.tar.xz'); |
|
21 |
define('WKHTMLTOPDF_WIN64_DOWNLOAD_URI', 'http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.0/wkhtmltox-win64_0.12.0-03c001d.exe'); |
|
22 |
define('WKHTMLTOPDF_WIN_DOWNLOAD_URI', 'http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.0/wkhtmltox-win32_0.12.0-03c001d.exe'); |
|
22 | 23 |
define('WKHTMLTOPDF_OSX_DOWNLOAD_URI', 'http://wkhtmltopdf.googlecode.com/files/wkhtmltopdf-OSX-0.10.0_rc2-static.tar.bz2'); |
23 | 24 |
|
24 | 25 |
/** |
... | ... | |
159 | 160 |
// Decompress the tar bz2 archive |
160 | 161 |
$arch_ret = drush_shell_exec('tar xjf ' . $filename); |
161 | 162 |
break; |
163 |
case 'application/x-xz': |
|
164 |
// Decompress the tar xz archive |
|
165 |
$arch_ret = drush_shell_exec('tar xJf %s', $filename); |
|
166 |
break; |
|
162 | 167 |
} |
163 | 168 |
} |
164 | 169 |
else { |
drupal7/sites/all/modules/print/print_pdf/print_pdf.info | ||
---|---|---|
1 | 1 |
name = "PDF version" |
2 | 2 |
description = "Adds the capability to export pages as PDF." |
3 |
core=7.x
|
|
3 |
core = 7.x
|
|
4 | 4 |
package = "Printer, email and PDF versions" |
5 | 5 |
dependencies[] = print |
6 |
files[] = print_pdf.module |
|
7 |
files[] = print_pdf.admin.inc |
|
8 |
files[] = print_pdf.pages.inc |
|
9 |
files[] = print_pdf.install |
|
10 |
files[] = print_pdf.views.inc |
|
6 |
files[] = print_pdf.class.inc |
|
11 | 7 |
configure = admin/config/user-interface/print/pdf |
12 | 8 |
|
13 |
; Information added by drupal.org packaging script on 2012-09-04
|
|
14 |
version = "7.x-1.2"
|
|
9 |
; Information added by Drupal.org packaging script on 2014-04-02
|
|
10 |
version = "7.x-1.3"
|
|
15 | 11 |
core = "7.x" |
16 | 12 |
project = "print" |
17 |
datestamp = "1346768900"
|
|
13 |
datestamp = "1396426750"
|
|
18 | 14 |
|
drupal7/sites/all/modules/print/print_pdf/print_pdf.install | ||
---|---|---|
103 | 103 |
'fields' => array( |
104 | 104 |
'path' => array( |
105 | 105 |
'type' => 'varchar', |
106 |
'length' => 128,
|
|
106 |
'length' => 255,
|
|
107 | 107 |
'not null' => TRUE, |
108 | 108 |
'description' => 'Page path', |
109 | 109 |
), |
Formats disponibles : Unified diff
Weekly update of contrib modules