Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117885372
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
17 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/kolab_api_service.php b/lib/kolab_api_service.php
index e2ba761..e90aa87 100644
--- a/lib/kolab_api_service.php
+++ b/lib/kolab_api_service.php
@@ -1,437 +1,461 @@
<?php
/*
+--------------------------------------------------------------------------+
| This file is part of the Kolab Web Admin Panel |
| |
| Copyright (C) 2011-2012, Kolab Systems AG |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU Affero General Public License as published |
| by the Free Software Foundation, either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/> |
+--------------------------------------------------------------------------+
| Author: Aleksander Machniak <machniak@kolabsys.com> |
| Author: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> |
+--------------------------------------------------------------------------+
*/
/**
* Interface class for Kolab Admin Services
*/
abstract class kolab_api_service
{
protected $cache = array();
protected $conf;
protected $controller;
protected $db;
protected $supported_types_db = array('group', 'resource', 'role', 'user');
protected $supported_types = array('domain', 'group', 'resource', 'role', 'user');
/**
* Class constructor.
*
* @param kolab_api_controller Controller
*/
public function __construct($ctrl)
{
$this->controller = $ctrl;
$this->conf = Conf::get_instance();
$this->db = SQL::get_instance();
}
/**
* Advertise this service's capabilities
*/
abstract public function capabilities($domain);
/**
* Returns attributes of specified user type.
*
* @param string $object_name Name of the object (user, group, etc.)
* @param int $type_id User type identifier
* @param bool $required Throws exception on empty ID
*
* @return array User type attributes
*/
protected function object_type_attributes($object_name, $type_id, $required = true)
{
if (!$object_name || !in_array($object_name, $this->supported_types)) {
return array();
}
if (empty($type_id)) {
if ($required) {
throw new Exception($this->controller->translate($object_name . '.notypeid'), 34);
}
return array();
}
$object_types = $this->object_types($object_name);
if (empty($object_types[$type_id])) {
if ($object_name == 'domain') {
$result = array(
'auto_form_fields' => array(),
'form_fields' => array(
'associateddomain' => array(
'type' => 'list'
),
),
'fields' => array(
'objectclass' => array(
'top',
'domainrelatedobject',
),
),
);
return $result;
}
else {
throw new Exception($this->controller->translate($object_name . '.invalidtypeid'), 35);
}
}
return $object_types[$type_id]['attributes'];
}
/**
* Detects object type ID for specified objectClass attribute value
*
* @param string $object_name Name of the object (user, group, etc.)
* @param array $attributes Array of attributes and values
*
* @return int Object type identifier
*/
protected function object_type_id($object_name, $attributes)
{
if ($object_name == 'domain') return 1;
$object_class = $attributes['objectclass'];
if (empty($object_class)) {
return null;
}
- $object_class = array_map('strtolower', $object_class);
$object_types = $this->object_types($object_name);
+
+ if (count($object_types) == 1) {
+ return key($object_types);
+ }
+
+ $object_class = array_map('strtolower', $object_class);
+ $object_keys = array_keys($attributes);
+ $keys_count = count($object_keys);
$type_score = -1;
+ $keys_score = 0;
$type_id = null;
//console("Data objectClasses: " . implode(", ", $object_class));
foreach ($object_types as $idx => $elem) {
$ref_class = $elem['attributes']['fields']['objectclass'];
if (empty($ref_class)) {
continue;
}
//console("Reference objectclasses for " . $elem['key'] . ": " . implode(", ", $ref_class));
// Eliminate the duplicates between the $data_ocs and $ref_ocs
$_object_class = array_diff($object_class, $ref_class);
$_ref_class = array_diff($ref_class, $object_class);
+ // Object classes score
$differences = count($_object_class) + count($_ref_class);
$commonalities = count($object_class) - $differences;
$elem_score = $differences > 0 ? ($commonalities / $differences) : $commonalities;
+ // Attributes score
+ if ($keys_count) {
+ $ref_keys = array_unique(array_merge(
+ array_keys((array) $elem['attributes']['auto_form_fields']),
+ array_keys((array) $elem['attributes']['form_fields']),
+ array_keys($elem['attributes']['fields'])
+ ));
+ $elem_keys_score = $keys_count - count(array_diff($object_keys, $ref_keys));
+ }
+
//console("\$object_class not in \$ref_class (" . $elem['key'] . "): " . implode(", ", $_object_class));
//console("\$ref_class not in \$object_class (" . $elem['key'] . "): " . implode(", ", $_ref_class));
- //console("Score for $object_name type " . $elem['name'] . ": " . $elem_score . "(" . $commonalities . "/" . $differences . ")");
+ //console("Score for $object_name type " . $elem['name'] . ": " . $elem_score . "(" . $commonalities . "/" . $differences . ") " . $elem_keys_score);
- if ($elem_score > $type_score) {
+ // Compare last and current element score
+ if ($elem_score > $type_score || ($elem_score == $type_score && $elem_keys_score > $keys_score)) {
$type_id = $idx;
$type_score = $elem_score;
+ $keys_score = $elem_keys_score;
}
// On the likely chance that the object is a resource (types of which likely have the same
// set of objectclass attribute values), consider the other attributes. (#853)
if ($object_name == 'resource') {
//console("From database", $elem);
//console("Element key is " . $elem['key'] . " and \$attributes['mail'] is " . $attributes['mail']);
if (strstr($attributes['mail'], "-" . $elem['key'] . "-")) {
$type_id = $idx;
$type_score = 10;
}
}
}
return $type_id;
}
/**
* Returns object types definitions.
*
* @param string $object_name Name of the object (user, group, etc.)
*
* @return array Object types.
*/
protected function object_types($object_name)
{
if (!$object_name || !in_array($object_name, $this->supported_types_db)) {
return array();
}
$conf = Conf::get_instance();
$devel_mode = $conf->get('kolab_wap', 'devel_mode');
if ($devel_mode == null) {
if (!empty($this->cache['object_types']) && !empty($this->cache['object_types'][$object_name])) {
return $this->cache['object_types'][$object_name];
}
}
$sql_result = $this->db->query("SELECT * FROM {$object_name}_types ORDER BY name");
$object_types = array();
while ($row = $this->db->fetch_assoc($sql_result)) {
$object_types[$row['id']] = array();
foreach ($row as $key => $value) {
if ($key != "id") {
if ($key == "attributes") {
$object_types[$row['id']][$key] = json_decode($value, true);
}
else {
$object_types[$row['id']][$key] = $value;
}
}
}
}
//console("Object types for " . $object_name, $object_types);
if ($devel_mode == null) {
return $this->cache['object_types'][$object_name] = $object_types;
} else {
return $object_types;
}
}
/**
* Parses input (for add/edit) attributes
*
* @param string $object_name Name of the object (user, group, etc.)
* @param array $attrs Entry attributes
*
* @return array Entry attributes
*/
protected function parse_input_attributes($object_name, $attribs)
{
$type_attrs = $this->object_type_attributes($object_name, $attribs['type_id']);
Log::trace("kolab_api_service::parse_input_attributes for $object_name: " . var_export($type_attrs, TRUE));
Log::trace("called with \$attribs: " . var_export($attribs, TRUE));
$form_service = $this->controller->get_service('form_value');
// With the result, start validating the input
$form_service->validate(null, $attribs);
$result = array();
if (isset($type_attrs['form_fields'])) {
foreach ($type_attrs['form_fields'] as $key => $value) {
Log::trace("Running parse input attributes for key $key");
if (empty($attribs[$key]) && empty($value['optional'])) {
Log::error("\$attribs['" . $key . "'] is empty, and the field is not optional");
throw new Exception("Missing input value for $key", 345);
}
else {
Log::trace("Either \$attribs['" . $key . "'] is empty or the field is optional");
$result[$key] = $attribs[$key];
}
}
}
if (isset($type_attrs['auto_form_fields'])) {
foreach ($type_attrs['auto_form_fields'] as $key => $value) {
if (empty($attribs[$key])) {
if (empty($value['optional'])) {
$attribs['attributes'] = array($key);
$res = $form_service->generate(null, $attribs);
$attribs[$key] = $res[$key];
$result[$key] = $attribs[$key];
}
} else {
$result[$key] = $attribs[$key];
}
}
}
if (isset($type_attrs['fields'])) {
foreach ($type_attrs['fields'] as $key => $value) {
if (!is_array($value)) {
$value2 = $this->conf->expand($value);
if ($value !== $value2) {
Log::trace("Made value " . var_export($value, TRUE) . " in to: " . var_export($value2, TRUE));
$value = $value2;
}
}
if (empty($attribs[$key])) {
$result[$key] = $type_attrs['fields'][$key] = $value;
} else {
$result[$key] = $attribs[$key] = $value;
}
}
}
Log::trace("parse_input_attributes result", $result);
return $result;
}
- protected function parse_list_attributes($post) {
+ protected function parse_list_attributes($post)
+ {
$attributes = Array();
// Attributes to return
if (!empty($post['attributes']) && is_array($post['attributes'])) {
// get only supported attributes
$attributes = array_intersect($this->list_attribs, $post['attributes']);
// need to fix array keys
$attributes = array_values($attributes);
}
if (empty($attributes)) {
$attributes = (array)$this->list_attribs[0];
}
return $attributes;
}
- protected function parse_list_params($post) {
+ protected function parse_list_params($post)
+ {
$params = Array();
if (!empty($post['sort_by'])) {
if (is_array($post['sort_by'])) {
$params['sort_by'] = Array();
foreach ($post['sort_by'] as $attrib) {
if (in_array($attrib, $this->list_attribs)) {
$params['sort_by'][] = $attrib;
}
}
} else {
// check if sort attribute is supported
if (in_array($post['sort_by'], $this->list_attribs)) {
$params['sort_by'] = $post['sort_by'];
}
}
}
if (!empty($post['sort_order'])) {
$params['sort_order'] = $post['sort_order'] == 'DESC' ? 'DESC' : 'ASC';
}
if (!empty($post['page'])) {
$params['page'] = $post['page'];
}
if (!empty($post['page_size'])) {
$params['page_size'] = $post['page_size'];
}
return $params;
}
- protected function parse_list_search($post) {
+ protected function parse_list_search($post)
+ {
$search = Array();
// Search parameters
if (!empty($post['search']) && is_array($post['search'])) {
if (array_key_exists('params', $post['search'])) {
$search = $post['search'];
} else {
$search['params'] = $post['search'];
}
if (!empty($post['search_operator'])) {
$search['operator'] = $post['search_operator'];
}
}
return $search;
}
/**
* Parses result attributes
*
* @param string $object_name Name of the object (user, group, etc.)
* @param array $attrs Entry attributes
*
* @return array Entry attributes
*/
protected function parse_result_attributes($object_name, $attrs = array())
{
//console("parse_result_attributes($object_name, \$attrs = ", $attrs);
if (empty($attrs) || !is_array($attrs)) {
return $attrs;
}
$conf = Conf::get_instance();
$auth = Auth::get_instance();
$dn = key($attrs);
$attrs = $attrs[$dn];
$extra_attrs = array();
// add group type id to the result
$attrs['type_id'] = $this->object_type_id($object_name, $attrs);
if (empty($attrs['type_id'])) {
if ($object_name == 'domain') {
$attrs['type_id'] = 1;
}
}
// Search for attributes associated with the type_id that are not part
// of the results returned earlier. Example: nsrole / nsroledn / aci, etc.
// @TODO: this should go to LDAP class
if ($attrs['type_id']) {
$uta = $this->object_type_attributes($object_name, $attrs['type_id']);
foreach ((array)$uta as $field_type => $attributes) {
foreach ($attributes as $attribute => $data) {
if (!array_key_exists($attribute, $attrs)) {
$extra_attrs[] = $attribute;
}
}
}
}
// Insert the persistent, unique attribute
$unique_attr = $conf->get('unique_attribute');
if (!$unique_attr) {
$unique_attr = 'nsuniqueid';
}
if (!array_key_exists($unique_attr, $attrs)) {
$extra_attrs[] = $unique_attr;
}
// Get extra attributes
if (!empty($extra_attrs)) {
$extra_attrs = $auth->get_entry_attributes($dn, $extra_attrs);
if (!empty($extra_attrs)) {
$attrs = array_merge($attrs, $extra_attrs);
}
}
// Replace unique attribute with 'id' key
$attrs['id'] = $attrs[$unique_attr];
unset($attrs[$unique_attr]);
return $attrs;
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Apr 6, 1:59 AM (1 w, 11 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18809628
Default Alt Text
(17 KB)
Attached To
Mode
rWAP webadmin
Attached
Detach File
Event Timeline