Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.324
diff -u -p -r1.324 form.inc
--- includes/form.inc	14 Mar 2009 20:13:26 -0000	1.324
+++ includes/form.inc	26 Mar 2009 20:08:59 -0000
@@ -1914,25 +1914,49 @@ function form_process_radios($element) {
  * @see system_elements(), filter_form()
  */
 function form_process_text_format($element) {
-  if (isset($element['#text_format'])) {
-    // Determine the form element parents and element name to use for the input
-    // format widget. This simulates the 'element' and 'element_format' pair of
-    // parents that filter_form() expects.
-    $element_parents = $element['#parents'];
-    $element_name = array_pop($element_parents);
-    $element_parents[] = $element_name . '_format';
-
-    // We need to break references, otherwise form_builder recurses infinitely.
-    $element['value'] = (array)$element;
-    $element['#type'] = 'markup';
-    $element['#theme'] = NULL;
-    $element['#theme_wrapper'] = NULL;
-    $element['format'] = filter_form($element['#text_format'], 1, $element_parents);
-
-    // We need to clear the #text_format from the new child otherwise we
-    // would get into an infinite loop.
-    unset($element['value']['#text_format']);
-    $element['value']['#weight'] = 0;
+  if (isset($element['#text_format'])) {    
+    if (filter_access($element['#text_format'])) {    // Determine the form element parents and element name to use for the input
+      // format widget. This simulates the 'element' and 'element_format' pair of
+      // parents that filter_form() expects.
+      $element_parents = $element['#parents'];
+      $element_name = array_pop($element_parents);
+      $element_parents[] = $element_name . '_format';
+      
+      // We need to break references, otherwise form_builder recurses infinitely.
+      $element['value'] = (array)$element;
+      $element['#type'] = 'markup';
+      $element['#theme'] = NULL;
+      $element['#theme_wrapper'] = NULL;
+      $element['format'] = filter_form($element['#text_format'], 1, $element_parents);
+
+      // We need to clear the #text_format from the new child otherwise we
+      // would get into an infinite loop.
+      unset($element['value']['#text_format']);
+      $element['value']['#weight'] = 0;
+    }
+    else {
+      // Disable field, ensure #value is the #default_value and limit height
+      $element['#disabled'] = TRUE;
+      $element['#value'] = $element['#default_value'];
+      if (isset($element['#rows']) && $element['#rows'] > 5) {
+        $element['#rows'] = 5;
+      }
+      // Disabled attribute is needed because #disabled has already been processed.
+      $element['#attributes']['disabled'] = 'disabled';
+
+      // Add read only title and description.
+      $element['#title'] .= t(' (read only)');
+      $element['#description'] .= t(' <b>You are not allowed to change this field.</b>');
+
+      // Disable unecessary resizable.
+      $element['#resizable'] = FALSE;
+
+      // Add fixed format.
+      $element['body_format'] = array(
+        '#type' => 'value',
+        '#value' => $element['#text_format'],
+      );
+    }
   }
   return $element;
 }
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1032
diff -u -p -r1.1032 node.module
--- modules/node/node.module	20 Mar 2009 19:18:10 -0000	1.1032
+++ modules/node/node.module	26 Mar 2009 20:09:45 -0000
@@ -291,8 +291,17 @@ function node_mark($nid, $timestamp) {
 
 /**
  * See if the user used JS to submit a teaser.
+ *
+ * Disables teaser feature if body field is disabled.
  */
 function node_teaser_js(&$form, &$form_state) {
+
+  // Disable teaser fields when body is disabled
+  if (!empty($form['body']['#disabled'])) {
+    unset($form['teaser_js']);
+    unset($form_state['values']['teaser_js']);
+  }
+  
   if (isset($form_state['input']['teaser_js'])) {
     // Glue the teaser to the body.
     if (trim($form_state['values']['teaser_js'])) {
@@ -330,6 +339,12 @@ function node_teaser_js(&$form, &$form_s
 function node_teaser_include_verify(&$form, &$form_state) {
   $message = '';
 
+  // Disable teaser fields when body is disabled, form state needs to be unset so that it is ignored
+  if (!empty($form['body']['#disabled'])) {
+    unset($form['teaser_include']);
+    unset($form_state['values']['teaser_include']);
+  }
+
   // $form_state['input'] is set only when the form is built for preview/submit.
   if (isset($form_state['input']['body']) && isset($form_state['values']['teaser_include']) && !$form_state['values']['teaser_include']) {
     // "teaser_include" checkbox is present and unchecked.
@@ -1947,7 +1962,7 @@ function node_feed($nids = FALSE, $chann
         $item->body = $content;
         unset($item->teaser);
       }
-    
+
       // Allow modules to modify the fully-built node.
       node_invoke_node($item, 'alter', $teaser, FALSE);
     }
@@ -2312,11 +2327,6 @@ function node_access($op, $node, $accoun
   if (empty($account)) {
     $account = $user;
   }
-  // If the node is in a restricted format, disallow editing.
-  if ($op == 'update' && !filter_access($node->format)) {
-    return FALSE;
-  }
-
   if (user_access('bypass node access', $account)) {
     return TRUE;
   }
Index: modules/node/node.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.test,v
retrieving revision 1.17
diff -u -p -r1.17 node.test
--- modules/node/node.test	8 Mar 2009 04:25:04 -0000	1.17
+++ modules/node/node.test	26 Mar 2009 20:09:47 -0000
@@ -363,6 +363,110 @@ class PageEditTestCase extends DrupalWeb
     $this->assertText($edit['title'], t('Title displayed.'));
     $this->assertText($edit['body'], t('Body displayed.'));
   }
+  /**
+   * Test edit page with special text format.
+   *
+   * Test if a normal user is able to edit the page but is not allowed to change
+   * the fields which use a text format he's not allowed to use.
+   */
+  function testEditLimitedPermission() {
+    $admin_user = $this->drupalCreateUser(array('administer filters', 'edit any page content', 'create page content'));
+    $normal_user = $this->drupalCreateUser(array('edit any page content', 'create page content'));
+
+    $this->drupalLogout();
+    $this->drupalLogin($admin_user);
+    // Create node to edit.
+
+
+    list($filtered, $full) = $this->checkFilterFormats();
+
+    $edit = array();
+    $edit['title'] = $this->randomName(8);
+    $edit['body'] = $this->randomName(16);
+    $edit['body_format'] = $full;
+    $this->drupalPost('node/add/page', $edit, t('Save'));
+
+    // Check that the node exists in the database.
+    $node = $this->drupalGetNodeByTitle($edit['title']);
+    $this->assertTrue($node, t('Node found in database.'));
+
+    // Check that "edit" link points to correct page.
+    $this->clickLink(t('Edit'));
+    $edit_url = url("node/$node->nid/edit", array('absolute' => true));
+    $actual_url = $this->getURL();
+    $this->assertEqual($edit_url, $actual_url, t('On edit page.'));
+
+    // Check that the title and body fields are displayed with the correct values.
+    $this->assertLink(t('Edit'), 0, t('Edit tab found.'));
+    $this->assertFieldByName('title', $edit['title'], t('Title field displayed.'));
+    $this->assertFieldByName('body', '<!--break-->' . $edit['body'], t('Body field displayed.'));
+
+    // Edit the content of the node.
+    $edit = array();
+    $edit['title'] = $this->randomName(8);
+    $edit['body'] = $this->randomName(16);
+    // Stay on the current page, without reloading.
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    // Check that the title and body fields are displayed with the updated values.
+    $this->assertText($edit['title'], t('Title displayed.'));
+    $this->assertText($edit['body'], t('Body displayed.'));
+
+    // Try to edit with normal user
+    $this->drupalLogout();
+    $this->drupalLogin($normal_user);
+
+    $this->drupalGet("node/$node->nid");
+
+    // Check that "edit" link points to correct page.
+    $this->clickLink(t('Edit'));
+    $edit_url = url("node/$node->nid/edit", array('absolute' => true));
+    $actual_url = $this->getURL();
+    $this->assertEqual($edit_url, $actual_url, t('On edit page.'));
+
+    // Check if body field is read only
+    $this->assertText(t('(read only)'), t('Body is marked read only'));
+    $this->assertText(t('You are not allowed to change this field.'), t('Description is available'));
+    $this->assertFieldByXPath("//textarea[@disabled='disabled' and @id='edit-body']", '<!--break-->' . $edit['body'], t('Body field is disabled'));
+
+    // Check if teaser is disabled
+    $this->assertNoFieldByXPath("//input[@class='teaser-button']", t('Join summary'), t('Join button is not available'));
+    $this->assertNoField('teaser_js', t('Teaser field is not available'));
+    $this->assertNoField('teaser_include', t('Teaser include checkbox is not available'));
+
+    // Try to "force" the change
+    $new_edit = array();
+    $new_edit['title'] = $this->randomName(8);
+    $new_edit['body'] = $this->randomName(16);
+    // Stay on the current page, without reloading.
+    $this->drupalPost(NULL, $new_edit, t('Save'));
+
+    // Check that only the title is displayed with the updated values, the body should use the old values
+    $this->assertText($new_edit['title'], t('New title displayed.'));
+    $this->assertText($edit['body'], t('Old body displayed.'));
+  }
+
+    /**
+   * Query the database to get the two basic formats.
+   *
+   * @return Array Array containing filtered and full filter ids.
+   */
+  function checkFilterFormats() {
+    $result = db_query('SELECT format, name FROM {filter_format}');
+
+    $filtered = -1;
+    $full = -1;
+    while ($format = db_fetch_object($result)) {
+      if ($format->name == 'Filtered HTML') {
+        $filtered = $format->format;
+      }
+      elseif ($format->name == 'Full HTML') {
+        $full = $format->format;
+      }
+    }
+
+    return array($filtered, $full);
+  }
 }
 
 class PagePreviewTestCase extends DrupalWebTestCase {
