summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2012-03-31 01:30:37 +0200
committerJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2012-03-31 01:30:37 +0200
commita228de1f80379cc29b58bf2673fd4e3d56e953cd (patch)
tree68e3e4062eeea84b7abfea347a2fb98849d5ccc2
parent8c9e624ba04739bdd723a86e5eed051287e0018d (diff)
downloadwebadmin-a228de1f80379cc29b58bf2673fd4e3d56e953cd.tar.gz
Take a stab at making groups editable (and users, ultimately)
-rw-r--r--lib/Auth.php15
-rw-r--r--lib/Auth/LDAP.php50
-rw-r--r--lib/api/kolab_api_service_group.php136
-rw-r--r--lib/api/kolab_api_service_user.php11
-rw-r--r--lib/client/kolab_client_task_group.php2
-rw-r--r--lib/client/kolab_client_task_user.php2
-rw-r--r--lib/kolab_client_task.php36
-rw-r--r--lib/locale/en_US.php2
-rw-r--r--public_html/js/kolab_admin.js50
9 files changed, 292 insertions, 12 deletions
diff --git a/lib/Auth.php b/lib/Auth.php
index dfafc06..936a8db 100644
--- a/lib/Auth.php
+++ b/lib/Auth.php
@@ -171,11 +171,21 @@ class Auth {
return $this->_auth[$_SESSION['user']->get_domain()]->find_user_groups($member_dn);
}
+ public function get_attribute($subject, $attribute)
+ {
+ return $this->_auth[$_SESSION['user']->get_domain()]->get_attribute($subject, $attribute);
+ }
+
public function group_add($attributes, $type=NULL)
{
return $this->_auth[$_SESSION['user']->get_domain()]->group_add($attributes, $type);
}
+ public function group_find_by_attribute($attribute)
+ {
+ return $this->_auth[$_SESSION['user']->get_domain()]->group_find_by_attribute($attribute);
+ }
+
public function group_info($groupdata)
{
return $this->_auth[$_SESSION['user']->get_domain()]->group_info($groupdata);
@@ -236,6 +246,11 @@ class Auth {
return $roles;
}
+ public function modify_entry_attributes($subject, $mod_array)
+ {
+ return $this->_auth[$_SESSION['user']->get_domain()]->modify_entry_attributes($subject, $mod_array);
+ }
+
public function primary_for_valid_domain($domain)
{
$this->domains = $this->list_domains();
diff --git a/lib/Auth/LDAP.php b/lib/Auth/LDAP.php
index 73701b7..1801328 100644
--- a/lib/Auth/LDAP.php
+++ b/lib/Auth/LDAP.php
@@ -243,6 +243,44 @@ class LDAP
return $attributes;
}
+ public function get_attribute($subject_dn, $attribute)
+ {
+ $result = ldap_read($this->conn, $subject_dn, '(objectclass=*)', (array)($attribute));
+ console($result);
+ }
+
+ public function group_find_by_attribute($attribute)
+ {
+ if (empty($attribute) || !is_array($attribute) || count($attribute) > 1) {
+ return false;
+ }
+
+ if (empty($attribute[key($attribute)])) {
+ return false;
+ }
+
+ $filter = "(&";
+
+ foreach ($attribute as $key => $value) {
+ $filter .= "(" . $key . "=" . $value . ")";
+ }
+
+ $filter .= ")";
+
+ $base_dn = $this->domain_root_dn($this->domain);
+
+ $result = self::normalize_result($this->search($base_dn, $filter, array_keys($attribute)));
+
+ if (count($result) > 0) {
+ error_log("Results found: " . implode(', ', array_keys($result)));
+ return $result;
+ }
+ else {
+ error_log("No result");
+ return false;
+ }
+ }
+
public function list_domains()
{
$domains = $this->domains_list();
@@ -320,6 +358,18 @@ class LDAP
return $roles;
}
+ public function modify_entry_attributes($subject_dn, $attributes)
+ {
+ $this->_bind($_SESSION['user']->user_bind_dn, $_SESSION['user']->user_bind_pw);
+
+ $result = ldap_mod_replace($this->conn, $subject_dn, $attributes['replace']);
+
+ if ($result)
+ return true;
+ else
+ return false;
+ }
+
public function user_add($attrs, $type = null)
{
if ($type == null) {
diff --git a/lib/api/kolab_api_service_group.php b/lib/api/kolab_api_service_group.php
index 33a71a7..329521e 100644
--- a/lib/api/kolab_api_service_group.php
+++ b/lib/api/kolab_api_service_group.php
@@ -127,6 +127,109 @@ class kolab_api_service_group extends kolab_api_service
return FALSE;
}
+ public function group_edit($getdata, $postdata)
+ {
+ $gta = $this->object_type_attributes('group', $postdata['type_id']);
+ $form_service = $this->controller->get_service('form_value');
+ $group_attributes = array();
+
+ $conf = Conf::get_instance();
+
+ $unique_attr = $conf->get('unique_attr');
+ if (!$unique_attr) {
+ $unique_attr = 'nsuniqueid';
+ }
+
+ if (isset($gta['form_fields'])) {
+ foreach ($gta['form_fields'] as $key => $value) {
+ if (!isset($postdata[$key]) || empty($postdata[$key])) {
+ throw new Exception("Missing input value for $key", 345);
+ }
+ else {
+ $group_attributes[$key] = $postdata[$key];
+ }
+ }
+ }
+
+ if (isset($gta['auto_form_fields'])) {
+ foreach ($gta['auto_form_fields'] as $key => $value) {
+ if (empty($postdata[$key])) {
+ $postdata['attributes'] = array($key);
+ $res = $form_service->generate($getdata, $postdata);
+ $postdata[$key] = $res[$key];
+ }
+ $group_attributes[$key] = $postdata[$key];
+ }
+ }
+
+ if (isset($gta['fields'])) {
+ foreach ($gta['fields'] as $key => $value) {
+ if (!isset($postdata[$key]) || empty($postdata[$key])) {
+ $group_attributes[$key] = $gta['fields'][$key];
+ } else {
+ $group_attributes[$key] = $postdata[$key];
+ }
+ }
+
+ $group_attributes[$unique_attr] = $postdata[$unique_attr];
+ }
+
+ $auth = Auth::get_instance();
+ $auth->connect();
+
+ // Now that values have been re-generated where necessary, compare
+ // the new group attributes to the original group attributes.
+ $_group = $auth->group_find_by_attribute(Array($unique_attr => $postdata[$unique_attr]));
+
+ if (!$_group) {
+ console("Could not find group");
+ return false;
+ }
+
+ $_group_dn = key($_group);
+ $_group = $this->group_info(Array('group' => $_group_dn), Array());
+
+ $mod_array = Array(
+ "add" => Array(),
+ "del" => Array(),
+ "replace" => Array(),
+ );
+
+ foreach ($_group as $_group_attr => $_group_value) {
+ if (array_key_exists($_group_attr, $group_attributes)) {
+ if (!($group_attributes[$_group_attr] === $_group_value)) {
+ console("Attribute $_group_attr changed from", $_group_value, "to", $group_attributes[$_group_attr]);
+ $mod_array['replace'][$_group_attr] = $_group_value;
+ }
+ } else {
+ // TODO: Since we're not shipping the entire object back and forth, and only post
+ // part of the data... we don't know what is actually removed (think modifiedtimestamp, etc.)
+ console("Group attribute not mentioned, but not explicitly removed... by assumption");
+ }
+ }
+
+ foreach ($group_attributes as $attr => $value) {
+ if (array_key_exists($attr, $_group)) {
+ if (!($_group[$attr] === $value)) {
+ $mod_array['replace'][$attr] = $value;
+ }
+ } else {
+ $mod_array['add'][$attr] = $value;
+ }
+ }
+
+ console($mod_array);
+
+ $result = $auth->modify_entry_attributes($_group_dn, $mod_array);
+
+ if ($result) {
+ return $mod_array;
+ }
+
+ return false;
+
+ }
+
/**
* Group information.
*
@@ -142,6 +245,7 @@ class kolab_api_service_group extends kolab_api_service
}
$auth = Auth::get_instance();
+ $conf = Conf::get_instance();
$result = $auth->group_info($getdata['group']);
// normalize result
@@ -152,6 +256,38 @@ class kolab_api_service_group extends kolab_api_service
// add group type id to the result
$result['type_id'] = $this->object_type_id('group', $result['objectclass']);
+ // Search for attributes associated with the type_id that are not part
+ // of the results returned earlier. Example: nsrole / nsroledn / aci, etc.
+ if ($result['type_id']) {
+ $uta = $this->object_type_attributes('group', $result['type_id']);
+ $attrs = array();
+
+ foreach ($uta as $field_type => $attributes) {
+ foreach ($attributes as $attribute => $data) {
+ if (!array_key_exists($attribute, $result)) {
+ $attrs[] = $attribute;
+ }
+ }
+ }
+
+ // Insert the persistent, unique attribute
+ $unique_attr = $conf->get('unique_attr');
+ if (!$unique_attr) {
+ $unique_attr = 'nsuniqueid';
+ }
+
+ if (!array_key_exists($unique_attr, $attrs)) {
+ $attrs[] = 'nsuniqueid';
+ }
+
+ if (!empty($attrs)) {
+ $attrs = $auth->user_attributes($result['entrydn'], $attrs);
+ if (!empty($attrs)) {
+ $result = array_merge($result, $attrs);
+ }
+ }
+ }
+
//console($result);
if ($result) {
diff --git a/lib/api/kolab_api_service_user.php b/lib/api/kolab_api_service_user.php
index 855518f..111456e 100644
--- a/lib/api/kolab_api_service_user.php
+++ b/lib/api/kolab_api_service_user.php
@@ -145,6 +145,7 @@ class kolab_api_service_user extends kolab_api_service
}
$auth = Auth::get_instance();
+ $conf = Conf::get_instance();
$user = $getdata['user'];
$result = $auth->user_info($user);
@@ -170,6 +171,16 @@ class kolab_api_service_user extends kolab_api_service
}
}
+ // Insert the persistent, unique attribute
+ $unique_attr = $conf->get('unique_attr');
+ if (!$unique_attr) {
+ $unique_attr = 'nsuniqueid';
+ }
+
+ if (!array_key_exists($unique_attr, $attrs)) {
+ $attrs[] = 'nsuniqueid';
+ }
+
if (!empty($attrs)) {
$attrs = $auth->user_attributes($result['entrydn'], $attrs);
if (!empty($attrs)) {
diff --git a/lib/client/kolab_client_task_group.php b/lib/client/kolab_client_task_group.php
index ba213de..eb20069 100644
--- a/lib/client/kolab_client_task_group.php
+++ b/lib/client/kolab_client_task_group.php
@@ -267,7 +267,7 @@ class kolab_client_task_group extends kolab_client_task
}
// Create form object and populate with fields
- $form = $this->form_create('group', $attribs, $sections, $fields, $fields_map, $data);
+ $form = $this->form_create('group', $attribs, $sections, $fields, $fields_map, $data, $add_mode);
$form->set_title(kolab_html::escape($title));
diff --git a/lib/client/kolab_client_task_user.php b/lib/client/kolab_client_task_user.php
index f4c6d02..d1e5b9f 100644
--- a/lib/client/kolab_client_task_user.php
+++ b/lib/client/kolab_client_task_user.php
@@ -307,7 +307,7 @@ class kolab_client_task_user extends kolab_client_task
}
// Create form object and populate with fields
- $form = $this->form_create('user', $attribs, $sections, $fields, $fields_map, $data);
+ $form = $this->form_create('user', $attribs, $sections, $fields, $fields_map, $data, $add_mode);
$form->set_title(kolab_html::escape($title));
diff --git a/lib/kolab_client_task.php b/lib/kolab_client_task.php
index 0662a97..b0ffba3 100644
--- a/lib/kolab_client_task.php
+++ b/lib/kolab_client_task.php
@@ -378,6 +378,9 @@ class kolab_client_task
*/
public function config_get($name, $fallback = null)
{
+ if ($name == "devel_mode")
+ return TRUE;
+
$value = $this->config->get('kolab_wap', $name);
return $value !== null ? $value : $fallback;
}
@@ -819,19 +822,32 @@ class kolab_client_task
$debug = str_replace("\n ", "\n", $debug);
$debug = '<pre class="debug">' . $debug . '</pre>';
$fields['debug'] = array(
- 'label' => 'debug',
- 'section' => 'system',
- 'value' => $debug,
- );
+ 'label' => 'debug',
+ 'section' => 'system',
+ 'value' => $debug,
+ );
}
}
// Add object type hidden field
$fields['object_type'] = array(
- 'section' => 'system',
- 'type' => kolab_form::INPUT_HIDDEN,
- 'value' => $name,
- );
+ 'section' => 'system',
+ 'type' => kolab_form::INPUT_HIDDEN,
+ 'value' => $name,
+ );
+
+ if (!$add_mode) {
+ $unique_attr = $this->config->get('unique_attr');
+ if (!$unique_attr) {
+ $unique_attr = 'nsuniqueid';
+ }
+
+ $fields[$unique_attr] = Array(
+ 'section' => 'system',
+ 'type' => kolab_form::INPUT_HIDDEN,
+ 'value' => $data[$unique_attr]
+ );
+ }
return array($fields, $types, $type);
}
@@ -848,7 +864,7 @@ class kolab_client_task
*
* @return kolab_form HTML Form object
*/
- protected function form_create($name, $attribs, $sections, $fields, $fields_map, $data)
+ protected function form_create($name, $attribs, $sections, $fields, $fields_map, $data, $add_mode)
{
// Assign sections to fields
foreach ($fields as $idx => $field) {
@@ -942,7 +958,7 @@ class kolab_client_task
$form->add_button(array(
'value' => kolab_html::escape($this->translate('submit.button')),
- 'onclick' => "kadm.{$name}_save()",
+ 'onclick' => $add_mode ? "kadm.{$name}_add()" : "kadm.{$name}_edit()",
));
if (!empty($data['entrydn'])) {
diff --git a/lib/locale/en_US.php b/lib/locale/en_US.php
index f156994..975dad2 100644
--- a/lib/locale/en_US.php
+++ b/lib/locale/en_US.php
@@ -90,6 +90,7 @@ $LANG['user.password.mismatch'] = 'Passwords do not match!';
$LANG['user.homeserver'] = 'Mailbox home server';
$LANG['user.add.success'] = 'User created successfully.';
$LANG['user.delete.success'] = 'User deleted successfully.';
+$LANG['user.edit.success'] = 'User edited successfully.';
$LANG['user.preferredlanguage'] = 'Native tongue';
$LANG['user.gidnumber'] = 'Primary group number';
$LANG['user.homedirectory'] = 'Home directory';
@@ -105,6 +106,7 @@ $LANG['group.mail'] = 'Primary Email Address';
$LANG['group.type_id'] = 'Group type';
$LANG['group.add.success'] = 'Group created successfully.';
$LANG['group.delete.success'] = 'Group deleted successfully.';
+$LANG['group.edit.success'] = 'Group edited successfully.';
$LANG['group.gidnumber'] = 'Primary group number';
$LANG['group.uniquemember'] = 'Members';
$LANG['group.system'] = 'System';
diff --git a/public_html/js/kolab_admin.js b/public_html/js/kolab_admin.js
index d035b49..8279b0c 100644
--- a/public_html/js/kolab_admin.js
+++ b/public_html/js/kolab_admin.js
@@ -1093,6 +1093,56 @@ function kolab_admin()
this.command('group.list', {page: page});
};
+ this.group_add = function(reload, section)
+ {
+ var data = this.serialize_form('#'+this.env.form_id);
+
+ if (reload) {
+ data.section = section;
+ this.http_post('group.add', {data: data});
+ return;
+ }
+
+ this.form_error_clear();
+
+ this.set_busy(true, 'saving');
+ this.api_post('group.add', data, 'group_add_response');
+ };
+
+ this.group_add_response = function(response)
+ {
+ if (!this.api_response(response))
+ return;
+
+ this.display_message('group.add.success');
+ this.command('group.list', {page: this.env.list_page});
+ };
+
+ this.group_edit = function(reload, section)
+ {
+ var data = this.serialize_form('#'+this.env.form_id);
+
+ if (reload) {
+ data.section = section;
+ this.http_post('group.edit', {data: data});
+ return;
+ }
+
+ this.form_error_clear();
+
+ this.set_busy(true, 'saving');
+ this.api_post('group.edit', data, 'group_edit_response');
+ };
+
+ this.group_edit_response = function(response)
+ {
+ if (!this.api_response(response))
+ return;
+
+ this.display_message('group.edit.success');
+ this.command('group.list', {page: this.env.list_page});
+ };
+
this.group_save = function(reload, section)
{
var data = this.serialize_form('#'+this.env.form_id);