Index: modules/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block.module,v
retrieving revision 1.154
diff -u -F^f -r1.154 block.module
--- modules/block.module	27 Feb 2005 02:48:57 -0000	1.154
+++ modules/block.module	27 Feb 2005 12:28:31 -0000
@@ -244,6 +244,17 @@ function block_admin_configure($module =
         $types = '';
       }
       db_query("UPDATE {blocks} SET visibility = %d, pages = '%s', custom = %d, types = '%s' WHERE module = '%s' AND delta = '%s'", $edit['visibility'], $edit['pages'], $edit['custom'], $types, $module, $delta);
+      
+      // Reset permissions for the block
+      db_query("DELETE FROM {block_access} WHERE module='%s' AND delta='%s'", $module, $delta);
+
+      if (isset($edit["roles"]) and is_array($edit["roles"])) {
+        foreach($edit["roles"] as $role) {
+          // Some roles provided: save them
+          db_query("INSERT INTO {block_access} (module, delta, rid) VALUES ('%s', '%s', '%d')", $module, $delta, $role);
+        }
+      }
+      
       module_invoke($module, 'block', 'save', $delta, $edit);
       drupal_set_message('The block configuration has been saved.');
       cache_clear_all();
@@ -255,6 +266,15 @@ function block_admin_configure($module =
         $edit = db_fetch_array(db_query("SELECT pages, visibility, custom, types FROM {blocks} WHERE module = '%s' AND delta = '%s'", $module, $delta));
       }
 
+      $roles_array = user_roles();
+      $roles_perm = array();
+      
+      $result = db_query("SELECT rid FROM {block_access} WHERE module='%s' AND delta='%s'", $module, $delta);
+      while ($result && ($row = db_fetch_object($result))) {
+        $roles_perm[] = $row->rid;
+      }
+      unset($result);
+      
       // Module-specific block configurations.
       if ($settings = module_invoke($module, 'block', 'configure', $delta)) {
         $form = form_group(t('Block-specific settings'), $settings);
@@ -272,12 +292,13 @@ function block_admin_configure($module =
       $group_2 = form_radios(t('Show block on specific pages'), 'visibility', $edit['visibility'], array(t('Show on every page except the listed pages.'), t('Show on only the listed pages.')));
       $group_2 .= form_textarea(t('Pages'), 'pages', $edit['pages'], 40, 5, t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are '<em>blog</em>' for the blog page and '<em>blog/*</em>' for every personal blog. '<em>&lt;front&gt;</em>' is the front page."));
       $group_3 = form_checkboxes(t('Restrict block to specific content types'), 'types', explode(',', $edit['types']), $content_types, t('Selecting one or more content types will cause this block to only be shown on pages of the selected types. This feature works alone or in conjunction with page specific visibility settings. For example, you can specify that a block only appear on book pages in the \'FAQ\' path.'), NULL, FALSE);
-
+      $group_4 = form_checkboxes(t('Show block to specific roles'), 'roles', $roles_perm, $roles_array, t('Selecting one or more roles will cause this block to only be shown if the current user belongs to one of the selected roles. If no role is selected, the block is showed to all. Selecting all roles or selecting none, has the same effect.'), NULL, FALSE);
+      
       $form .= form_group(t('User specific visibility settings'), $group_1);
       $form .= form_group(t('Page specific visibility settings'), $group_2);
       $form .= form_group(t('Content specific visibility settings'), $group_3);
-
-
+      $form .= form_group(t('Role specific visibility settings'), $group_4);
+      
       $form .= form_submit(t('Save block'));
 
       print theme('page', form($form));
@@ -462,7 +483,29 @@ function block_list($region) {
         $type_match = TRUE;
       }
 
-      if ($enabled && $page_match && $type_match) {
+      // Test if the user resides in at least one role that can access (view) the block
+      $role_match = TRUE;
+      $role_result = null;
+      $roles = array();
+      
+      if ($user->uid != 1) {
+        $role_result = db_query("SELECT ba.rid, r.name FROM {block_access} ba, {role} r WHERE ba.module='%s' AND ba.delta='%s' AND r.rid = ba.rid", $block["module"], $block["delta"]);
+      }
+      
+      while ($row = db_fetch_object($role_result)) {
+        $roles[$row->rid] = $row->name;
+      }
+
+      if (count($roles) && $user->roles && count(array_intersect($roles, $user->roles)) == 0) {
+        $role_match = FALSE;
+      }
+      unset($role_result);
+      
+      if ($enabled && $page_match && $type_match && $role_match) {
         // Check the current throttle status and see if block should be displayed
         // based on server load.
         if (!($block['throttle'] && (module_invoke('throttle', 'status') > 0))) {
Index: modules/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user.module,v
retrieving revision 1.443
diff -u -F^f -r1.443 user.module
--- modules/user.module	27 Feb 2005 02:15:57 -0000	1.443
+++ modules/user.module	27 Feb 2005 12:28:31 -0000
@@ -1525,6 +1525,7 @@ function user_admin_role() {
   else if ($op == t('Delete role')) {
     db_query('DELETE FROM {role} WHERE rid = %d', $id);
     db_query('DELETE FROM {permission} WHERE rid = %d', $id);
+    db_query('DELETE FROM {block_access} WHERE rid = %d', $id);
 
     // Update the users who have this role set:
     $result = db_query('SELECT DISTINCT(ur1.uid) FROM {users_roles} ur1 LEFT JOIN {users_roles} ur2 ON ur2.uid = ur1.uid WHERE ur1.rid = %d AND ur2.rid != ur1.rid', $id);
Index: database/database.pgsql
===================================================================
RCS file: /cvs/drupal/drupal/database/database.pgsql,v
retrieving revision 1.105
diff -u -F^f -r1.105 database.pgsql
--- database/database.pgsql	21 Feb 2005 19:47:44 -0000	1.105
+++ database/database.pgsql	27 Feb 2005 12:28:31 -0000
@@ -44,6 +44,16 @@
 );
 
 --
+-- Table structure for block_access
+--
+
+CREATE TABLE block_access (
+  module varchar(64) NOT NULL default '',
+  delta varchar(32) NOT NULL default '0',
+  rid integer NOT NULL default '0'
+);
+
+--
 -- Table structure for blocks
 --
 
Index: database/database.mysql
===================================================================
RCS file: /cvs/drupal/drupal/database/database.mysql,v
retrieving revision 1.170
diff -u -F^f -r1.170 database.mysql
--- database/database.mysql	21 Feb 2005 19:47:44 -0000	1.170
+++ database/database.mysql	27 Feb 2005 12:28:31 -0000
@@ -114,6 +114,16 @@
 ) TYPE=MyISAM;
 
 --
+-- Table structure for table 'block_access'
+--
+
+CREATE TABLE block_access (
+  module varchar(64) NOT NULL default '',
+  delta varchar(32) NOT NULL default '0',
+  rid int(10) unsigned NOT NULL default '0'
+) TYPE=MyISAM;
+
+--
 -- Table structure for table 'blocks'
 --
 
Index: database/updates.inc
===================================================================
RCS file: /cvs/drupal/drupal/database/updates.inc,v
retrieving revision 1.92
diff -u -F^f -r1.92 updates.inc
--- database/updates.inc	23 Feb 2005 06:04:59 -0000	1.92
+++ database/updates.inc	27 Feb 2005 12:28:31 -0000
@@ -100,7 +100,8 @@
   "2005-01-26" => "update_121",
   "2005-01-27" => "update_122",
   "2005-01-28" => "update_123",
-  "2005-02-11" => "update_124"
+  "2005-02-11" => "update_124",
+  "2005-02-27" => "update_125"
 );
 
 function update_32() {
@@ -2275,6 +2276,27 @@ function update_124() {
   return $ret;
 }
 
+function update_125() {
+  $ret = array();
+  
+  if ($GLOBALS['db_type'] == 'mysql') {
+    $ret[] = update_sql("CREATE TABLE block_access (
+    module varchar(64) NOT NULL default '',
+    delta varchar(32) NOT NULL default '0',
+    rid int(10) unsigned NOT NULL default '0'
+    )");
+  }
+  elseif ($GLOBALS['db_type'] == 'pgsql') {  
+    $ret[] = update_sql("CREATE TABLE block_access (
+    module varchar(64) NOT NULL default '',
+    delta varchar(32) NOT NULL default '0',
+    rid integer NOT NULL default '0'
+    )");
+  }
+  
+  return $ret;
+}
+
 function update_sql($sql) {
   $edit = $_POST["edit"];
   $result = db_query($sql);
