Code

Updated post handling
[gosa.git] / gosa-core / plugins / generic / references / class_aclResolver.inc
index 9e178f422b545abf4e46ada4e55a6f6a11b50be0..51d05a510ddd1482c628245949a72e090263725d 100644 (file)
@@ -2,27 +2,37 @@
 
 class aclResolver 
 {
-
     private $classMapping = array();
     private $aclTypes = array();
     private $affectingACLs = array();
 
+    private $renderedList = "";
+
+    // The users 'dn' and 'uid' used to verify the collected acls
+    private $validateDn;
+    private $validateUid;
+    private $acl_category;
+    private $parent;
+
+    // Used for the autocompleter
+    private $userMap;
+
     function __construct($config, $dn, $parent)
     {
         $this->config = &$config;
         $this->dn = $dn;
+        $this->parent = $parent;
 
-        // Get ACL category for the current object.
-        if(isset($parent->acl_category) && !empty($parent->acl_category)){
-            $this->acl_category = preg_replace("/\/$/","",$parent->acl_category);
-        }
+        // Replace this with a user defined one later.
+        $ui = get_userinfo();
+        $this->validateUid = $ui->uid;
+        $this->validateDn = $ui->dn;
 
-        // Build class mapping
+        // Build class mapping - only once, will not change during session.
         if(!session::is_set('aclConverter::classMapping')){
             $tmp= session::global_get('plist');
             $plist= $tmp->info;
             $map = array();
-            $map['all']= _("All categories");
             foreach($plist as $class => $plInfo){
                 if(isset($plInfo['plCategory']) && is_array($plInfo['plCategory'])){
                     foreach($plInfo['plCategory'] as $category => $desc){
@@ -48,107 +58,267 @@ class aclResolver
         }
         $this->classMapping = session::get('aclConverter::classMapping');
 
-        // Go through all ACLs and get those matching out DN.
+        // Define ACL type translations
+        $this->aclTypes= array("reset" => _("Reset ACLs"),
+                "one" => _("One level"),
+                "base" => _("Current object"),
+                "sub" => _("Complete subtree"),
+                "psub" => _("Complete subtree (permanent)"),
+                "role" => _("Use ACL defined in role"));
+    
+        // Enforce to reload acl result 
+        $this->renderedList = "";
+    }
+
+    
+    function reload()
+    {
+        // Go through all ACLs and get those matching the objects dn.
         $ui = get_userinfo();
+        $ui->reset_acl_cache();
+        $ui->loadACL();
+
+        // Get ACL category for the current object.
+        if(isset($this->parent->acl_category) && !empty($this->parent->acl_category)){
+            $this->acl_category = preg_replace("/\/$/","",$this->parent->acl_category);
+        }
+
         foreach($ui->allACLs as $dn => $acls){
             if(preg_match("/".preg_quote($dn,'/')."$/i", $this->dn)){
+
+                // Foreach dn there is a collection of ACLs indexed by their priority
                 foreach($acls as $prio => $acl){
                     if($acl['type'] == "reset"){
                         $this->affectingACLs[$dn][$prio] = $acl;
-                        break;
+                        continue;
                     }else{
+
+                        // Only get those entries with a relevant acl-category
                         foreach($acl['acl'] as $category => $attributes){
                             if(preg_match("/^all($|\/)/", $category) || 
                                     preg_match("/^".$this->acl_category."($|\/)/", $category)){
                                 $this->affectingACLs[$dn][$prio] = $acl;
-                                break;
+                                continue;
                             }
                         }
                     }
                 }
             }
         }
-
-        // Define ACL type translations
-        $this->aclTypes= array("reset" => _("Reset ACLs"),
-                "one" => _("One level"),
-                "base" => _("Current object"),
-                "sub" => _("Complete subtree"),
-                "psub" => _("Complete subtree (permanent)"),
-                "role" => _("Use ACL defined in role"));
     }
+    
 
 
     /*! \brief   Create a human readable HTML result 
      */    
     function getReadableACL() 
     {
-        $str = "<table summary='"._("Object permissions")."' width='100%'>";
-        foreach($this->affectingACLs as $dn => $acls){
-            foreach($acls as $acl){
-                $str.="<tr>"; 
-                if(isset($this->config->idepartments[$dn])){
-                    $image= image("images/select_department.png");
-                }else{
-                    $image= image("images/lists/element.png");
-                }
+        if(isset($_POST['aclTarget'])){
+            $d = get_post('aclTarget');
+            if(isset($this->userMap[$d])){
+                $this->validateDn = $this->userMap[$d]['dn'];
+                $this->validateUid = $this->userMap[$d]['uid'][0];
+                $this->renderedList = "";
+            }
+        }
+       
+        if(empty($this->renderedList)){
 
-                $str.="<td style='width:20px;'>".$image."</td>";
-                $str.="<td><b>".$dn."</b></td>";
-                $str.="<td rowspan=3>".$this->aclTypes[$acl['type']]."</td>";
-                $str.="</tr><tr>";
-                $str.="<td></td><td><b>"._("Members")."</b><ul>";
-                foreach($acl['members'] as $type => $name){
-                    $str .= "<li>".$name."</li>";
-                }
-                $str .= "</ul>"; 
-                $str .= "</td>"; 
-                $str .= "</tr><tr><td></td>";
+            $this->reload();
 
-                if($acl['type']!='reset'){
-                    $str.="<td><b>"._("Acls")."</b><ul>";
-                    foreach($acl['acl'] as $type => $acl){
+            // Autocompleter template 
+            $autocompleter ="
+                <input class='filter_textfield' placeholder='"._("Enter another user name")."...' 
+                id='aclTarget' name='aclTarget' type='text' value='' 
+                onChange=\"\$('aclTargetSubmit').focus();\">
 
-                        if(isset($this->classMapping[$type])){
-                            $str .= "<li>".$this->classMapping[$type].": ".$this->aclToString($acl)."</li>";
-                        }else{
-                            $str .= "<li>".$type.": ".$this->aclToString($acl)."</li>";
+                <div id='autocomplete' class='autocomplete'></div>
+                <script type='text/javascript'>
+                new Ajax.Autocompleter(
+                        'aclTarget', 
+                        'autocomplete', 
+                        'autocomplete.php', 
+                        { minChars: 3, frequency: 0.5 });
+            </script>
+            ".image("images/lists/submit.png","aclTargetSubmit");
+
+            // Base template - each entry start with this 
+            $tpl = 
+                "\n <tr class='acl-viewer-head %s'>".
+                "\n  <td style='width:20px'>%s</td>".
+                "\n  <td colspan=2><b>%s</b><div class='right'>%s</div></td>".
+                "\n </tr>".
+                "\n %s";
+
+            // If the acl consists of a user-object-filter then this template is used.        
+            $filter_tpl = 
+                "\n <tr class='%s'>".
+                "\n  <td></td>".
+                "\n  <td><b>"._("Filter")."</b></td>".
+                "\n  <td><ul class='acl-viewer-items'><li>%s</li></ul></td>".
+                "\n </tr>";
+
+            // Used to display ACL owner of type "group"
+            $gmem_tpl = 
+                "\n <tr class='%s'>".
+                "\n  <td></td>".
+                "\n  <td><b>"._("Groups")."</b></td>".
+                "\n  <td><ul class='acl-viewer-items'>%s</ul></td>".
+                "\n </tr>";
+
+            // Used to display ACL owner of type "user"
+            $umem_tpl = 
+                "\n <tr class='%s'>".
+                "\n  <td></td>".
+                "\n  <td><b>"._("Users")."</b></td>".
+                "\n  <td><ul class='acl-viewer-items'>%s</ul></td>".
+                "\n </tr>";
+
+            // Used to display the acl contents, except 'reset' and 'role'
+            $acl_tpl = 
+                "\n <tr class='%s'>".
+                "\n  <td></td>".
+                "\n  <td><b>"._("Acls")."</b></td>".
+                "\n  <td><ul class='acl-viewer-items'>%s</ul></td>".
+                "\n </tr>";
+
+
+            $user = "<h3>".sprintf(_("List of effective ACLs for '%s'"), $this->validateUid)."</h3>";
+            $str  = "<table summary='"._("Object permissions")."'>";
+            $str .= " <tr><td>".$user."</td><td>".$autocompleter."</td></tr>";
+            $str .= "</table>";
+            $str .= "<div class='acl-viewer-container'>";
+            $str .= "<table summary='"._("Object permissions")."' cellpadding='0' cellspacing='0' class='acl-viewer'>";
+            $ldap = $this->config->get_ldap_link();
+            $ldap->cd($this->config->current['BASE']);
+            $ui = get_userinfo();
+            foreach($this->affectingACLs as $dn => $acls){
+                foreach($acls as $acl){
+
+                    // Prepare entry icon (department or element?)
+                    $image = (isset($this->config->idepartments[$dn]))? "images/select_department.png":"images/lists/element.png";
+
+                    // The acl type (sub,psub,reset...)
+                    $aclType = $this->aclTypes[$acl['type']];
+
+                    // Does the filter match for current object? 
+                    $filter ="";
+                    $match = TRUE;
+                    if(!empty($acl['filter'])){
+                        $match = $ldap->object_match_filter($this->dn,$acl['filter']);
+                        $filter= $acl['filter'];
+                        if(!$match){
+                            $filter= "<span>".$filter."</span>";
+                        }
+                    }
+
+                    // Check membership 
+                    $gmem = $umem = "";
+                    $users = $groups = array();
+                    $found = FALSE;
+                    foreach($acl['members'] as $type => $name){
+
+                        // Check if we're part of the members 
+                        if(preg_match("/^U:/", $type)){
+                            if(preg_match("/^U:".preg_quote($this->validateDn,'/')."/", $type)){
+                                $users[] = $name;
+                                $found = TRUE;
+                                continue;
+                            }
+                            $users[] = "<span>".$name."</span>";
+                        }
+
+                        // Check if we're part of the group members 
+                        if(preg_match("/^G/", $type)){
+                            if($type == "G:*"){
+                                $found = TRUE;
+                                $groups[] = $name;
+                                continue;
+                            }
+                            if(preg_match("/^G:/", $type)){
+                                $gdn = preg_replace("/^G:/","",$type);
+                                $ldap->cat($gdn,array('memberUid'));
+                                if($ldap->count()){
+                                    $attrs = $ldap->fetch();
+                                    if(isset($attrs['memberUid']) && in_array($this->validateUid, $attrs['memberUid'])){
+                                        $found = TRUE;
+                                        $groups[] = $name;
+                                        continue;
+                                    }
+                                }
+                            }
+
+                            // Mark groups that doesn't match 
+                            $groups[] = "<span>".$name."</span>";
                         }
                     }
-                    $str .= "</ul>"; 
-                    $str .= "</td>"; 
-                    $str .= "</tr>"; 
-                }else{
-                    $str .= "<td></td>";
+
+                    // Build up ACL definition list 
+                    $defs ="";
+                    if($acl['type']!='reset'){
+                        foreach($acl['acl'] as $type => $acl){
+                            if(isset($this->classMapping[$type])){
+                                $defs .= "<li>".$this->classMapping[$type].": ".$this->aclToString($acl)."</li>";
+                            }else{
+                                $defs .= "<li>".$type.": ".$this->aclToString($acl)."</li>";
+                            }
+                        }
+                    }
+                   
+                    // Display the acl block in a special color if its not matching 
+                    $class="";
+                    if(!$found || !$match){
+                        $class = "acl-viewer-blocked";
+                    }                    
+                    if(!empty($filter)) $filter =sprintf($filter_tpl,$class,$filter);
+                    if(!empty($defs)) $defs = sprintf($acl_tpl,$class,$defs);
+                    if(count($users))  $umem = sprintf($umem_tpl,$class,"<li>".implode($users,'</li><li>')."</li>");
+                    if(count($groups)) $gmem = sprintf($gmem_tpl,$class,"<li>".implode($groups,'</li><li>')."</li>");
+                    $str.= sprintf($tpl,$class, image($image), $dn, $aclType, $filter.$gmem.$umem.$defs);
                 }
-                $str .= "<tr><td colspan=3><hr></td></tr>"; 
             }
+            $str .= "</table>"; 
+            $str .= "</div>"; 
+            $this->renderedList = $str;
         }
-        $str .= "</table>"; 
-        return($str);
+        return($this->renderedList);
     }
 
     function aclToString($acls)
     {
-        $str ="<ul>";
+        $str ="<ul class='acl-category-list'>";
         foreach($acls as $name => $acl){
-
             if($name == "0") $name = _("All");
-
-            $str .= "<li>".$name.": <i>";
-
-            if(preg_match("/r/", $acl)) $str.= _("read").', '; 
-            if(preg_match("/w/", $acl)) $str.= _("write").', '; 
-            if(preg_match("/c/", $acl)) $str.= _("Create").', '; 
-            if(preg_match("/d/", $acl)) $str.= _("Remove").', '; 
-            if(preg_match("/m/", $acl)) $str.= _("Move").', '; 
-            if(preg_match("/s/", $acl)) $str.= _("Owner").', '; 
-            $str = trim($str,', ');
-            $str.= "</i></li>";
+            $str .= "<li><i>".$name.":</i> ";
+            $str .= "<ul class='acl-list'>";
+            if(preg_match("/s/", $acl)){
+                $str.="<li><u>"._("Restrict changes to user's own object").'</u></li>'; 
+            }
+            if(preg_match("/r/", $acl)) $str.="<li>"._("read").'</li>'; 
+            if(preg_match("/w/", $acl)) $str.="<li>"._("write").'</li>'; 
+            if(preg_match("/c/", $acl)) $str.="<li>"._("create").'</li>'; 
+            if(preg_match("/d/", $acl)) $str.="<li>"._("remove").'</li>'; 
+            if(preg_match("/m/", $acl)) $str.="<li>"._("move").'</li>'; 
+            $str.= "</ul>";
         }
         return($str."</ul>");
     }
+
+    function processAutocomplete()
+    {
+            $ldap = $this->config->get_ldap_link();
+            $ldap->cd($this->config->current['BASE']);
+            $ldap->search("(&(objectClass=gosaAccount)(|(sn=*".get_post('aclTarget')."*)".
+                    "(uid=*".get_post('aclTarget')."*)(givenName=*".get_post('aclTarget')."*)))",
+                    array('uid','dn','sn','givenName'));
+            echo "<ul>";
+            while($attrs = $ldap->fetch()){
+                $display = $attrs['givenName'][0]." ".$attrs['sn'][0]." [".$attrs['uid'][0]."]";
+                echo "<li>{$display}</li>";
+                $this->userMap[$display] = $attrs;
+            }
+            echo "</ul>";
+    }
 }
 
 ?>
-