Complete the permission handling.
authorGunnar Wrobel <p@rdus.de>
Mon, 4 May 2009 06:07:18 +0000 (08:07 +0200)
committerGunnar Wrobel <p@rdus.de>
Mon, 4 May 2009 06:07:18 +0000 (08:07 +0200)
koward/lib/Koward.php
koward/lib/Koward/Controller/Application.php
koward/lib/Koward/Controller/ObjectController.php
koward/lib/Koward/Form/Actions.php
koward/lib/Koward/Form/Object.php
koward/lib/Koward/View/Object/add.html.php [new file with mode: 0644]
koward/lib/Koward/View/Object/listall.html.php
koward/lib/Koward/View/Object/view.html.php
koward/package.xml

index 0f226aa..a0d110c 100644 (file)
 
 class Koward {
 
-    const PERM_GET = 1;
+    const PERM_SHOW = 1;
+    const PERM_READ = 2;
+    const PERM_EDIT = 4;
+    const PERM_DELETE = 8;
 
     /**
      * The singleton instance.
@@ -206,6 +209,12 @@ class Koward {
         }
     }
 
+
+    public function hasAccess($id, $permission = Koward::PERM_SHOW)
+    {
+        return $this->hasPermission($id, null, $permission);
+    }
+
     /**
      * In the long run we might wish to use the Horde permission system
      * here. But for the first draft this would be too much as the permission
@@ -217,24 +226,21 @@ class Koward {
                                         $id, $perm);
 
         if ($user === null) {
-            $session = Horde_Kolab_Session::singleton();
-            if (!empty($session->user_uid)) {
-                $user = $this->getObject($session->user_uid);
+            try {
+                $session = Horde_Kolab_Session::singleton();
+                if (!empty($session->user_uid)) {
+                    $user = $this->getObject($session->user_uid);
+                    $type = $this->getType($user);
+                    if (isset($this->objects[$type]['permission'])) {
+                        return $this->_hasPermission($this->objects[$type]['permission'],
+                                                     $id, $perm);
+                    }
+                }
+            } catch (Exception $e) {
+                Horde::logMessage($e->getMessage(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
             }
         }
-
-        if (empty($user)) {
-            return $global;
-        }
-
-        if (isset($this->objects[$type]['permission'])) {
-            $object = $this->_hasPermission($this->objects[$type]['permission'],
-                                            $id, $perm);
-        } else {
-            return $global;
-        }
-
-        return $objects || $global;
+        return $global;
     }
 
     private function _hasPermission(&$root, $id, $perm)
@@ -246,6 +252,9 @@ class Koward {
             return $perm & $root;
         }
         if (is_array($root)) {
+            if (empty($id)) {
+                return true;
+            }
             list($sub, $path) = explode('/', $id, 2);
             if (!isset($root[$sub])) {
                 return false;
index 96e29e9..0fd97e7 100644 (file)
@@ -29,16 +29,7 @@ class Koward_Controller_Application extends Horde_Controller_Base
             throw new Koward_Exception('No object types have been configured!');
         }
 
-        if (!$this->koward->hasPermission($this->getPermissionId(), null, Koward::PERM_GET)) {
-            $this->koward->notification->push(_("Access denied."), 'horde.error');
-            if (Auth::getAuth()) {
-                $url = $this->urlFor(array('controller' => 'index', 'action' => 'index'));
-            } else {
-                $url = $this->urlFor(array('controller' => 'index', 'action' => 'login'));
-            }
-            header('Location: ' . $url);
-            exit;
-        }
+        $this->checkAccess();
 
         $this->menu = $this->getMenu();
 
@@ -58,12 +49,21 @@ class Koward_Controller_Application extends Horde_Controller_Base
         require_once 'Horde/Menu.php';
         $menu = new Menu();
 
-        $menu->add($this->urlFor(array('controller' => 'object', 'action' => 'listall')),
-                   _("_Objects"), 'user.png', $registry->getImageDir('horde'));
-        $menu->add($this->urlFor(array('controller' => 'object', 'action' => 'edit')),
-                   _("_Add"), 'plus.png', $registry->getImageDir('horde'));
-        $menu->add($this->urlFor(array('controller' => 'object', 'action' => 'search')),
-                   _("_Search"), 'search.png', $registry->getImageDir('horde'));
+        if ($this->koward->hasAccess('object/listall')) {
+            $menu->add($this->urlFor(array('controller' => 'object', 'action' => 'listall')),
+                       _("_Objects"), 'user.png', $registry->getImageDir('horde'));
+        }
+
+        if ($this->koward->hasAccess('object/add', Koward::PERM_EDIT)) {
+            $menu->add($this->urlFor(array('controller' => 'object', 'action' => 'add')),
+                       _("_Add"), 'plus.png', $registry->getImageDir('horde'));
+        }
+
+        if ($this->koward->hasAccess('object/search')) {
+            $menu->add($this->urlFor(array('controller' => 'object', 'action' => 'search')),
+                       _("_Search"), 'search.png', $registry->getImageDir('horde'));
+        }
+
         if (!empty($this->koward->conf['koward']['menu']['queries'])) {
             $menu->add(Horde::applicationUrl('Queries'), _("_Queries"), 'query.png', $registry->getImageDir('koward'));
         }
@@ -82,4 +82,22 @@ class Koward_Controller_Application extends Horde_Controller_Base
     {
         return $this->params['controller'] . '/' . $this->params['action'];
     }
+
+    public function checkAccess($id = null, $permission = Koward::PERM_SHOW)
+    {
+        if ($id === null) {
+            $id = $this->getPermissionId();
+        }
+
+        if (!$this->koward->hasAccess($id, $permission)) {
+            $this->koward->notification->push(_("Access denied."), 'horde.error');
+            if (Auth::getAuth()) {
+                $url = $this->urlFor(array('controller' => 'index', 'action' => 'index'));
+            } else {
+                $url = $this->urlFor(array('controller' => 'index', 'action' => 'login'));
+            }
+            header('Location: ' . $url);
+            exit;
+        }
+    }
 }
index 1157b17..ef3b585 100644 (file)
@@ -23,6 +23,13 @@ class ObjectController extends Koward_Controller_Application
 
         $this->object_type = $this->params->get('id', $this->types[0]);
 
+        $this->checkAccess($this->getPermissionId() . '/' . $this->object_type);
+
+        $this->allowEdit = $this->koward->hasAccess('object/edit/' . $this->object_type,
+                                                    Koward::PERM_EDIT);
+        $this->allowDelete = $this->koward->hasAccess('object/delete/' . $this->object_type,
+                                                      Koward::PERM_DELETE);
+
         if (isset($this->koward->objects[$this->object_type]['list_attributes'])) {
             $this->attributes = $this->koward->objects[$this->object_type]['list_attributes'];
         } else if (isset($this->koward->objects[$this->object_type]['attributes']['fields'])) {
@@ -54,15 +61,20 @@ class ObjectController extends Koward_Controller_Application
                     _("Delete")) . Horde::img('delete.png', _("Delete"), '',
                                               $GLOBALS['registry']->getImageDir('horde'))
                     . '</a>';
-                $this->objectlist[$uid]['view_url'] = Horde::link(
-                    $this->urlFor(array('controller' => 'object', 
-                                        'action' => 'view',
-                                        'id' => $uid)), _("View"));
+                if ($this->koward->hasAccess('object/view/' . $this->object_type, Koward::PERM_READ)) {
+                    $this->objectlist[$uid]['view_url'] = Horde::link(
+                        $this->urlFor(array('controller' => 'object', 
+                                            'action' => 'view',
+                                            'id' => $uid)), _("View"));
+                }
             }
         }
 
         $this->tabs = new Horde_UI_Tabs(null, Variables::getDefaultVariables());
         foreach ($this->koward->objects as $key => $configuration) {
+            if (!$this->koward->hasAccess($this->getPermissionId() . '/' . $key)) {
+                continue;
+            }
             $this->tabs->addTab($configuration['list_label'],
                                 $this->urlFor(array('controller' => 'object', 
                                                     'action' => 'listall',
@@ -81,6 +93,10 @@ class ObjectController extends Koward_Controller_Application
                                                  'horde.error');
             } else {
                 $this->object = $this->koward->getObject($this->params->id);
+
+                $this->checkAccess($this->getPermissionId() . '/' . $this->koward->getType($this->object),
+                                   Koward::PERM_DELETE);
+
                 $this->submit_url = $this->urlFor(array('controller' => 'object',
                                                         'action' => 'delete',
                                                         'id' => $this->params->id,
@@ -127,10 +143,29 @@ class ObjectController extends Koward_Controller_Application
 
                 $this->object = $this->koward->getObject($this->params->id);
 
+                $this->object_type = $this->koward->getType($this->object);
+
+                $this->checkAccess($this->getPermissionId() . '/' . $this->object_type,
+                                   Koward::PERM_READ);
+
+                $this->allowEdit = $this->koward->hasAccess('object/edit/' . $this->object_type,
+                                                            Koward::PERM_EDIT);
+
                 $actions = $this->object->getActions();
                 if (!empty($actions)) {
+                    $buttons = array();
+                    foreach ($actions as $action) {
+                        if (isset($this->koward->objects[$this->object_type]['actions'][$action])
+                            && $this->koward->hasAccess('object/action/' . $this->object_type . '/' . $action,
+                                                        Koward::PERM_EDIT)) {
+                            $buttons[] = $this->koward->objects[$this->object_type]['actions'][$action];
+                        }
+                    }
+                }
+                    
+                if (!empty($buttons)) {
                     try {
-                        $this->actions = new Koward_Form_Actions($this->object);
+                        $this->actions = new Koward_Form_Actions($buttons);
 
                         $this->post = $this->urlFor(array('controller' => 'object', 
                                                       'action' => 'view',
@@ -169,15 +204,46 @@ class ObjectController extends Koward_Controller_Application
         $this->render();
     }
 
+    public function add()
+    {
+        $this->object = null;
+
+        require_once 'Horde/Util.php';
+        $type = Util::getFormData('type');
+
+        if (!empty($type)) {
+            $this->checkAccess($this->getPermissionId() . '/' . $type,
+                               Koward::PERM_EDIT);
+        } else {
+            $this->checkAccess($this->getPermissionId(),
+                               Koward::PERM_EDIT);
+        }
+
+        $this->_edit();
+    }
+
     public function edit()
     {
-        try {
-            if (empty($this->params->id)) {
-                $this->object = null;
-            } else {
+        if (empty($this->params->id)) {
+            $this->koward->notification->push(_("The object that should be viewed has not been specified."),
+                                              'horde.error');
+        } else {
+            try {
                 $this->object = $this->koward->getObject($this->params->id);
+            } catch (Exception $e) {
+                $this->koward->notification->push($e->getMessage(), 'horde.error');
             }
 
+            $this->checkAccess($this->getPermissionId() . '/' . $this->koward->getType($this->object),
+                               Koward::PERM_EDIT);
+
+            $this->_edit();
+        }
+    }
+
+    private function _edit()
+    {
+        try {
             require_once 'Horde/Variables.php';
             $this->vars = Variables::getDefaultVariables();
             foreach ($this->params as $key => $value) {
@@ -205,8 +271,8 @@ class ObjectController extends Koward_Controller_Application
             $this->koward->notification->push($e->getMessage(), 'horde.error');
         }
 
-        $this->post = $this->urlFor(array('controller' => 'object'
-                                          'action' => 'edit',
+        $this->post = $this->urlFor(array('controller' => $this->params['controller']
+                                          'action' => $this->params['action'],
                                           'id' => $this->params->id));
 
         $this->render();
index 2dadc8b..69db861 100644 (file)
@@ -15,33 +15,14 @@ class Koward_Form_Actions extends Horde_Form {
      */
     protected $koward;
 
-    public function __construct(&$object)
+    public function __construct($buttons)
     {
         $this->koward = &Koward::singleton();
 
-        $this->object = &$object;
-
         parent::Horde_Form(Variables::getDefaultVariables());
 
         $this->setTitle(_("Object actions"));
 
-        $class_name = get_class($this->object);
-        foreach ($this->koward->objects as $name => $config) {
-            if ($config['class'] == $class_name) {
-                $this->type = $name;
-                if (!empty($config['preferred'])) {
-                    break;
-                }
-            }
-        }
-
-        $buttons = array();
-        foreach ($this->object->getActions() as $action) {
-            if (isset($this->koward->objects[$this->type]['actions'][$action])) {
-                $buttons[] = $this->koward->objects[$this->type]['actions'][$action];
-            }
-        }
-
         if (!empty($buttons)) {
             $this->setButtons($buttons);
         }
index 5eb7ddb..dc80017 100644 (file)
@@ -30,6 +30,9 @@ class Koward_Form_Object extends Horde_Form {
             $this->setButtons(_("Add"));
 
             foreach ($this->koward->objects as $key => $config) {
+                if (!$this->koward->hasAccess('object/add/' . $key, Koward::PERM_EDIT)) {
+                    continue;
+                }
                 $options[$key] = $config['label'];
             }
             
diff --git a/koward/lib/Koward/View/Object/add.html.php b/koward/lib/Koward/View/Object/add.html.php
new file mode 100644 (file)
index 0000000..5185924
--- /dev/null
@@ -0,0 +1,4 @@
+<?= $this->renderPartial('header'); ?>
+<?= $this->renderPartial('menu'); ?>
+<?= $this->form->renderActive(new Horde_Form_Renderer(), $this->vars,
+                              $this->post, 'post'); ?>
\ No newline at end of file
index a790967..724ac0a 100644 (file)
@@ -8,8 +8,12 @@
 <table cellspacing="0" width="100%" class="linedRow">
  <thead>
   <tr>
-   <th class="item" width="1%"><?php echo Horde::img('edit.png', _("Edit"), '', $GLOBALS['registry']->getImageDir('horde')) ?></th>
-   <th class="item" width="1%"><?php echo Horde::img('delete.png', _("Delete"), '', $GLOBALS['registry']->getImageDir('horde')) ?></th>
+   <?php if ($this->allowEdit): ?>
+    <th class="item" width="1%"><?php echo Horde::img('edit.png', _("Edit"), '', $GLOBALS['registry']->getImageDir('horde')) ?></th>
+   <?php endif; ?>
+   <?php if ($this->allowDelete): ?>
+    <th class="item" width="1%"><?php echo Horde::img('delete.png', _("Delete"), '', $GLOBALS['registry']->getImageDir('horde')) ?></th>
+   <?php endif; ?>
    <?php foreach ($this->attributes as $attribute => $info): ?>
      <th class="item leftAlign" width="<?php echo $info['width'] ?>%" nowrap="nowrap"><?= $info['title'] ?></th>
    <?php endforeach; ?>
  <tbody>
   <?php foreach ($this->objectlist as $dn => $info): ?>
   <tr>
-   <td>
-    <?= $info['edit_url'] ?>
-   </td> 
-   <td>
-    <?= $info['delete_url'] ?>
-   </td> 
+   <?php if ($this->allowEdit): ?>
+    <td>
+     <?= $info['edit_url'] ?>
+    </td> 
+   <?php endif; ?>
+   <?php if ($this->allowDelete): ?>
+    <td>
+     <?= $info['delete_url'] ?>
+    </td> 
+   <?php endif; ?>
    <?php foreach ($this->attributes as $attribute => $ainfo): ?>
    <td>
    <?php if (!empty($ainfo['link_view'])): ?>
index b9da7d2..282be96 100644 (file)
@@ -9,5 +9,7 @@ if (isset($this->actions)) {
 if (isset($this->form)) {
     echo $this->form->renderInactive(new Horde_Form_Renderer(), $this->vars);
 
-    echo $this->edit;
+    if ($this->allowEdit) {
+        echo $this->edit;
+    }
 }
index 89cdc56..a9241c6 100644 (file)
@@ -82,6 +82,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
        <file name="login.html.php" role="php" />
       </dir> <!-- /lib/Koward/View/Index -->
       <dir name="Object">
+       <file name="add.html.php" role="php" />
        <file name="delete.html.php" role="php" />
        <file name="edit.html.php" role="php" />
        <file name="listall.html.php" role="php" />
@@ -305,6 +306,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
    <install name="lib/Koward/View/Check/show.html.php" as="Koward/View/Check/show.html.php" />
    <install name="lib/Koward/View/Index/index.html.php" as="Koward/View/Index/index.html.php" />
    <install name="lib/Koward/View/Index/login.html.php" as="Koward/View/Index/login.html.php" />
+   <install name="lib/Koward/View/Object/add.html.php" as="Koward/View/Object/add.html.php" />
    <install name="lib/Koward/View/Object/delete.html.php" as="Koward/View/Object/delete.html.php" />
    <install name="lib/Koward/View/Object/edit.html.php" as="Koward/View/Object/edit.html.php" />
    <install name="lib/Koward/View/Object/listall.html.php" as="Koward/View/Object/listall.html.php" />