diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index fa04624b29de1b0083d7bc92f8b65b62d32d58ae..520447dc2078922758e6481fe3903ca64d5e0c19 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -1021,9 +1021,9 @@ class DynamicFormEntry extends VerySimpleModel {
         return $this->form;
     }
 
-    function getForm() {
+    function getForm($source=false, $options=array()) {
         if (!isset($this->_form)) {
-            // XXX: Should source be $this?
+
             $fields = $this->getFields();
             if (isset($this->extra)) {
                 $x = JsonDataParser::decode($this->extra) ?: array();
@@ -1031,13 +1031,16 @@ class DynamicFormEntry extends VerySimpleModel {
                     unset($fields[$id]);
                 }
             }
-            $form = new SimpleForm($fields, $this->getSource(),
-            array(
+
+            $source = $source ?: $this->getSource();
+            $options += array(
                 'title' => $this->getTitle(),
-                'instructions' => $this->getInstructions(),
-            ));
-            $this->_form = $form;
+                'instructions' => $this->getInstructions()
+                );
+            $this->_form = new CustomForm($fields, $source, $options);
         }
+
+
         return $this->_form;
     }
 
@@ -1102,15 +1105,14 @@ class DynamicFormEntry extends VerySimpleModel {
      * $filter - (callback) function to receive each field and return
      *      boolean true if the field's errors are significant
      */
-    function isValid($filter=false) {
+    function isValid($filter=false, $options=array()) {
+
         if (!is_array($this->_errors)) {
-            $this->_errors = array();
-            $this->getClean();
-            foreach ($this->getFields() as $field) {
-                if ($field->errors() && (!$filter || $filter($field)))
-                    $this->_errors[$field->get('id')] = $field->errors();
-            }
+            $form = $this->getForm(false, $options);
+            $form->isValid($filter);
+            $this->_errors = $form->errors();
         }
+
         return !$this->_errors;
     }
 
diff --git a/include/class.forms.php b/include/class.forms.php
index 2b85a204f9871e5610aa00a837f8f153dfa3cdbe..146aa898fdeb9b22948f9acf6ccc677f66a01fde 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -22,6 +22,7 @@ class Form {
     static $renderer = 'GridFluidLayout';
     static $id = 0;
 
+    var $options = array();
     var $fields = array();
     var $title = '';
     var $instructions = '';
@@ -33,6 +34,7 @@ class Form {
 
     function __construct($source=null, $options=array()) {
 
+        $this->options = $options;
         if (isset($options['title']))
             $this->title = $options['title'];
         if (isset($options['instructions']))
@@ -321,6 +323,25 @@ class SimpleForm extends Form {
     }
 }
 
+class CustomForm extends SimpleForm {
+
+    function getFields() {
+
+        $options = $this->options;
+        $user = @$options['user'];
+        $isedit = ($options['mode'] == 'edit');
+        $fields = array();
+        foreach (parent::getFields() as $field) {
+            if ($isedit && !$field->isEditable($user))
+                continue;
+
+            $fields[] = $field;
+        }
+
+        return $fields;
+    }
+}
+
 abstract class AbstractForm extends Form {
     function __construct($source=null, $options=array()) {
         parent::__construct($source, $options);
@@ -665,14 +686,21 @@ class FormField {
     }
 
     /**
-     * FIXME: Temp
+     * Check if the user has edit rights
      *
      */
 
-    function isEditable() {
-        return (($this->get('flags') & DynamicFormField::FLAG_MASK_EDIT) == 0);
+    function isEditable($user=null) {
+
+        if ($user instanceof EndUser)
+            $flag = DynamicFormField::FLAG_CLIENT_EDIT;
+        else
+            $flag = DynamicFormField::FLAG_AGENT_EDIT;
+
+        return (($this->get('flags') & $flag) != 0);
     }
 
+
     /**
      * isStorable
      *