| 5 |
* Restrict access to any drupal path on a per user role basis |
* Restrict access to any drupal path on a per user role basis |
| 6 |
* |
* |
| 7 |
* @author: Mike Carter <mike@ixis.co.uk> |
* @author: Mike Carter <mike@ixis.co.uk> |
| 8 |
* @usage: ?q=admin/access/path to configure path restrictions per role. |
* @author: CSÉCSY László <boobaa.no@spam.kybest.hu> |
| 9 |
|
* @usage: ?q=admin/user/pathaccess to configure path restrictions per role. |
| 10 |
*/ |
*/ |
| 11 |
|
|
| 12 |
/** |
/** |
| 13 |
* Implementation of hook_help(). |
* Implementation of hook_help(). |
| 14 |
*/ |
*/ |
| 15 |
function path_access_help($section) { |
function path_access_help($path, $arg) { |
| 16 |
switch ($section) { |
switch ($path) { |
| 17 |
case 'admin/help#access': |
case 'admin/user/pathaccess': |
|
return t('blah'); |
|
|
case 'admin/modules#description': |
|
|
return t('Controls user access to any path'); |
|
|
case 'admin/access/path': |
|
| 18 |
return t('Each user role can be granted or denied access to any url paths. This is a crude but straight forward way to restrict groups of nodes/pages to certain users using only the paths associated with the pages. Page access is not limited to node pages only, anything can be controlled using paths.'); |
return t('Each user role can be granted or denied access to any url paths. This is a crude but straight forward way to restrict groups of nodes/pages to certain users using only the paths associated with the pages. Page access is not limited to node pages only, anything can be controlled using paths.'); |
| 19 |
} |
} |
| 20 |
} |
} |
| 21 |
|
|
| 22 |
function _path_access_stringquote(&$item1, $key) { |
/** |
| 23 |
$item1 = "'{$item1}'"; |
* Implementation of hook_init(). |
| 24 |
} |
*/ |
|
|
|
| 25 |
function path_access_init() { |
function path_access_init() { |
| 26 |
global $user; |
global $user; |
| 27 |
|
|
| 31 |
if ($user->uid == 1) { |
if ($user->uid == 1) { |
| 32 |
return 1; |
return 1; |
| 33 |
} |
} |
| 34 |
|
// This one does not work in D6 without the role_weights module, so the user's last role_id will be taken into account. |
| 35 |
|
// $role = module_exists('role_weights') ? module_invoke('role_weights', 'get_highest', $user->roles) : array('name' => $user->roles); |
| 36 |
|
foreach($user->roles as $k => $v) { |
| 37 |
|
$role = $k; |
| 38 |
|
} |
| 39 |
|
|
| 40 |
$role = module_invoke('role_weights', 'get_highest', $user->roles); |
$result = db_query('SELECT pages, visibility FROM {path_access} WHERE rid = %d', $role); |
|
$result = db_query("SELECT pages, visibility FROM {path_access} pa INNER JOIN {role} r ON r.rid = pa.rid WHERE r.name = '%s'", $role['name']); |
|
| 41 |
|
|
| 42 |
$visibility = 1; |
$visibility = 1; |
| 43 |
$pages = ''; |
$pages = ''; |
| 47 |
} |
} |
| 48 |
$visibility = $visibility > 0 ? true : false; |
$visibility = $visibility > 0 ? true : false; |
| 49 |
|
|
| 50 |
// Match path if necessary |
// Match path if necessary. |
| 51 |
if ($pages) { |
if ($pages) { |
| 52 |
// The current page |
// The current page. |
| 53 |
$path = drupal_get_path_alias($_GET['q']); |
$path = drupal_get_path_alias(check_plain($_GET['q'])); |
| 54 |
|
|
| 55 |
$regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. variable_get('site_frontpage', 'node') .'\2'), preg_quote($pages, '/')) .')$/'; |
$regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. variable_get('site_frontpage', 'node') .'\2'), preg_quote($pages, '/')) .')$/'; |
| 56 |
$page_match = ($visibility xor preg_match($regexp, $path)); |
$page_match = ($visibility xor preg_match($regexp, $path)); |
| 59 |
$page_match = FALSE; |
$page_match = FALSE; |
| 60 |
} |
} |
| 61 |
|
|
| 62 |
|
// Check that the current page is not a protected page before blocking user. |
|
// Check that the current page is not a protected page before blocking user |
|
| 63 |
if($page_match && !path_access_protected_pages($path)) { |
if($page_match && !path_access_protected_pages($path)) { |
|
// Initialize locale |
|
|
$GLOBALS['locale'] = locale_initialize(); |
|
| 64 |
drupal_access_denied(); |
drupal_access_denied(); |
| 65 |
exit; |
exit; |
| 66 |
} |
} |
|
|
|
| 67 |
} |
} |
| 68 |
|
|
|
|
|
| 69 |
/** |
/** |
| 70 |
* Implementation of hook_menu(). |
* Implementation of hook_menu(). |
| 71 |
*/ |
*/ |
| 72 |
function path_access_menu($may_cache) { |
function path_access_menu() { |
| 73 |
$items = array(); |
$items = array(); |
| 74 |
|
$items['admin/user/pathaccess/edit'] = array( |
| 75 |
if ($may_cache) { |
'title' => t('configure role paths'), |
| 76 |
$items[] = array('path' => 'admin/access/path/edit', 'title' => t('configure role paths'), |
'page callback' => 'path_access_admin_role_configure', |
| 77 |
'access' => user_access('administer url aliases'), |
'access arguments' => array('administer url aliases'), |
| 78 |
'callback' => 'path_access_admin_role_configure', |
'type' => MENU_CALLBACK, |
| 79 |
'type' => MENU_CALLBACK); |
); |
| 80 |
$items[] = array('path' => 'admin/access/path', 'title' => t('urls'), |
$items['admin/user/pathaccess'] = array( |
| 81 |
'access' => user_access('administer url aliases'), |
'title' => t('Path Access'), |
| 82 |
'callback' => 'path_access_admin_roles', |
'description' => t('Define what paths a user role can access.'), |
| 83 |
'type' => MENU_LOCAL_TASK); |
'page callback' => 'path_access_admin_roles', |
| 84 |
} |
'access arguments' => array('administer url aliases'), |
| 85 |
|
'type' => MENU_NORMAL_ITEM, |
| 86 |
|
); |
| 87 |
return $items; |
return $items; |
| 88 |
} |
} |
| 89 |
|
|
|
|
|
| 90 |
/** |
/** |
| 91 |
* Menu callback; displays the block configuration form. |
* Menu callback; displays the block configuration form. |
| 92 |
*/ |
*/ |
| 93 |
function path_access_admin_roles() { |
function path_access_admin_roles() { |
|
|
|
| 94 |
// Render the role overview. |
// Render the role overview. |
| 95 |
$result = db_query('SELECT * FROM {role} ORDER BY name'); |
$result = db_query('SELECT * FROM {role} ORDER BY name'); |
| 96 |
|
|
| 97 |
$header = array(t('Name'), t('Operations')); |
$header = array(t('User Role'), t('Operations')); |
| 98 |
while ($role = db_fetch_object($result)) { |
while ($role = db_fetch_object($result)) { |
| 99 |
$rows[] = array($role->name, l(t('edit'), 'admin/access/path/edit/'. $role->rid)); |
$rows[] = array($role->name, l(t('edit'), 'admin/user/pathaccess/edit/'. $role->rid)); |
| 100 |
} |
} |
|
|
|
| 101 |
$output = theme('table', $header, $rows); |
$output = theme('table', $header, $rows); |
| 102 |
|
return $output; |
|
print theme('page', $output); |
|
| 103 |
} |
} |
| 104 |
|
|
|
|
|
| 105 |
/** |
/** |
| 106 |
* Menu callback; displays the block configuration form. |
* Menu callback; displays the configuration form. |
| 107 |
*/ |
*/ |
| 108 |
function path_access_admin_role_configure($module = NULL, $delta = 0) { |
function path_access_admin_role_configure() { |
| 109 |
$edit = $_POST['edit']; |
$roleid = (integer)arg(4); |
| 110 |
$op = $_POST['op']; |
|
| 111 |
$roleid = arg(4); |
$settings = db_fetch_array(db_query('SELECT * FROM {path_access} pa INNER JOIN {role} r ON pa.rid = r.rid WHERE pa.rid = %d', $roleid)); |
| 112 |
|
|
| 113 |
switch ($op) { |
// Obtain role name for the page if there is no existing path settings for this role id. |
| 114 |
case t('Save path access'): |
if(!$settings) { |
| 115 |
if ($edit['types']) { |
$rolename = db_result(db_query('SELECT name FROM {role} WHERE rid = %d', $roleid)); |
| 116 |
$types = implode(',', $edit['types']); |
db_query("INSERT INTO {path_access} (rid, pages, visibility) VALUES (%d, '', '')", $roleid); |
| 117 |
} |
} else { |
| 118 |
else { |
$rolename = $settings['name']; |
| 119 |
$types = ''; |
} |
|
} |
|
|
|
|
|
db_query("UPDATE {path_access} SET visibility = %d, pages = '%s' WHERE rid = %d", $edit['visibility'], $edit['pages'], $roleid); |
|
|
|
|
|
drupal_set_message('The path access configuration has been saved.'); |
|
|
drupal_goto('admin/access/path'); |
|
|
break; |
|
|
|
|
|
default: |
|
|
if (!$edit) { |
|
|
$edit = db_fetch_array(db_query("SELECT * FROM {path_access} pa INNER JOIN {role} r ON pa.rid = r.rid WHERE pa.rid = %d", $roleid)); |
|
|
|
|
|
// Obtain role name for the page |
|
|
if(!$edit) { |
|
|
$rolename = db_result(db_query("SELECT name FROM {role} WHERE rid = %d", $roleid)); |
|
|
$pid = db_next_id('path_access'); |
|
|
db_query("INSERT INTO {path_access} (pid, rid, pages, visibility) VALUES (%d, %d, '', '')", $pid, $roleid); |
|
|
} else { |
|
|
$rolename = $edit['name']; |
|
|
} |
|
|
} |
|
|
|
|
|
drupal_set_title(t("Path access for '%role' role", array('%role' => $rolename))); |
|
|
|
|
|
$form['page_vis_settings'] = array( |
|
|
'#type' => 'fieldset', |
|
|
'#title' => t('Page specific visibility settings'), |
|
|
'#collapsible' => FALSE, |
|
|
); |
|
|
$form['page_vis_settings']['visibility'] = array( |
|
|
'#type' => 'radios', |
|
|
'#title' => t('Allow users to view specific pages'), |
|
|
'#options' => array(t('Access every page except the listed pages.'), t('Access only the listed pages.')), |
|
|
'#default_value' => $edit['visibility'], |
|
|
); |
|
|
$form['page_vis_settings']['pages'] = array( |
|
|
'#type' => 'textarea', |
|
|
'#title' => t('Pages'), |
|
|
'#default_value' => $edit['pages'], |
|
|
'#description' => t("Enter one page per line as a path. The '*' character is a wildcard. Example paths are '<em>blog</em>' for the blog page and '<em>blog/*</em>' for every personal blog. '<em><front></em>' is the front page."), |
|
|
); |
|
|
$form['submit'] = array( |
|
|
'#type' => 'submit', |
|
|
'#value' => t('Save path access'), |
|
|
); |
|
| 120 |
|
|
| 121 |
|
drupal_set_title(t("Path access for '%role' role", array('%role' => $rolename))); |
| 122 |
|
|
| 123 |
|
return drupal_get_form('path_access_admin_configure_form', $settings); |
| 124 |
|
} |
| 125 |
|
|
| 126 |
|
/** |
| 127 |
|
* Define role access form. |
| 128 |
|
*/ |
| 129 |
|
function path_access_admin_configure_form(&$form_state, $edit) { |
| 130 |
|
$form['page_vis_settings'] = array( |
| 131 |
|
'#type' => 'fieldset', |
| 132 |
|
'#title' => t('Page specific visibility settings'), |
| 133 |
|
'#collapsible' => FALSE, |
| 134 |
|
); |
| 135 |
|
$form['page_vis_settings']['visibility'] = array( |
| 136 |
|
'#type' => 'radios', |
| 137 |
|
'#title' => t('Allow users to view specific pages'), |
| 138 |
|
'#options' => array(t('Access every page except the listed pages.'), t('Access only the listed pages.')), |
| 139 |
|
'#default_value' => $edit['visibility'], |
| 140 |
|
); |
| 141 |
|
$form['page_vis_settings']['pages'] = array( |
| 142 |
|
'#type' => 'textarea', |
| 143 |
|
'#title' => t('Pages'), |
| 144 |
|
'#default_value' => $edit['pages'], |
| 145 |
|
'#description' => t("Enter one page per line as a path. The '*' character is a wildcard. Example paths are '<em>blog</em>' for the blog page and '<em>blog/*</em>' for every personal blog. '<em><front></em>' is the front page."), |
| 146 |
|
); |
| 147 |
|
$form['submit'] = array( |
| 148 |
|
'#type' => 'submit', |
| 149 |
|
'#value' => t('Save path access'), |
| 150 |
|
); |
| 151 |
|
$form['rid'] = array('#type' => 'value', '#value' => $edit['rid']); |
| 152 |
|
|
| 153 |
|
return $form; |
| 154 |
|
} |
| 155 |
|
|
| 156 |
|
function path_access_admin_configure_form_validate($form_id, &$form_state) { |
| 157 |
|
// Prevent the logout page from being listed. |
| 158 |
|
$pages = explode("\n", $form_state['values']['pages']); |
| 159 |
|
|
| 160 |
return drupal_get_form('pathaccess_admin_configure', $form); |
if(in_array('logout', $pages)) { |
| 161 |
|
form_set_error('pages', t('You cannot block access to the %logout page.', array('%logout' => 'logout'))); |
| 162 |
} |
} |
| 163 |
} |
} |
| 164 |
|
|
| 165 |
|
/** |
| 166 |
|
* Process role access form submission |
| 167 |
|
*/ |
| 168 |
|
function path_access_admin_configure_form_submit($form_id, &$form_state) { |
| 169 |
|
db_query("UPDATE {path_access} SET visibility = %d, pages = '%s' WHERE rid = %d", $form_state['values']['visibility'], $form_state['values']['pages'], $form_state['values']['rid']); |
| 170 |
|
|
| 171 |
|
drupal_set_message(t('The path access configuration has been saved.')); |
| 172 |
|
$form_state['redirect'] = 'admin/user/pathaccess'; |
| 173 |
|
} |
| 174 |
|
|
| 175 |
/* |
/* |
| 176 |
* Protected Pages can never be restricted using path_access |
* Protected Pages can never be restricted using path_access. |
| 177 |
*/ |
*/ |
| 178 |
function path_access_protected_pages($page) { |
function path_access_protected_pages($page) { |
| 179 |
$pages = array('logout'); |
$pages = array('logout'); |
|
|
|
| 180 |
return in_array($page, $pages); |
return in_array($page, $pages); |
| 181 |
} |
} |
| 182 |
|
|
| 183 |
|
// vim: set ft=php syntax=php expandtab ts=2 sw=2 autoindent smartindent: |