Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
17 KB
Referenced Files
None
Subscribers
None
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

Mime Type
text/x-diff
Expires
Mon, Apr 6, 1:59 AM (1 w, 9 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18809628
Default Alt Text
(17 KB)

Event Timeline