[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Freeipa-devel] [PATCHES] 0016-17 Fixes for{add, set, del}attr with managed attributes



Patch 16 defers validation & conversion until after {add,del,set}attr is processed, so that we don't search for an integer in a list of strings (this caused ticket #2405), and so that the end result of these operations is validated (#2407).


Patch 17 makes these options honor params marked no_create and no_update.


https://fedorahosted.org/freeipa/ticket/2405
https://fedorahosted.org/freeipa/ticket/2407
https://fedorahosted.org/freeipa/ticket/2408


--
PetrĀ³
From c0063003f85de64b08e3d6d39cb0ca60a8cb07c2 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pviktori redhat com>
Date: Fri, 24 Feb 2012 12:26:28 -0500
Subject: [PATCH 16/17] Defer conversion and validation until after
 --{add,del,set}attr are handled

--addattr & friends that modified attributes known to Python sometimes
used converted and validated Python values instead of LDAP strings.
This caused a problem for --delattr, which searched for a converted
integer in a list of raw strings (ticket 2407).
With this patch we work on raw strings, converting only when done.

Deferring validation ensures the end result is valid, so proper errors
are raised instead of failing later (ticket 2405).

https://fedorahosted.org/freeipa/ticket/2405
https://fedorahosted.org/freeipa/ticket/2407
---
 ipalib/plugins/baseldap.py |   33 +++++++++++++++++++--------------
 1 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index 725704ee0e2d784a1f5ad8691d90888366f8efec..55d93eb28e3d9e41ca43a0cd04755d44c9f7240a 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -759,8 +759,6 @@ last, after all sets and adds."""),
         Convert a string in the form of name/value pairs into a dictionary.
         The incoming attribute may be a string or a list.
 
-        Any attribute found that is also a param is validated.
-
         :param attrs: A list of name/value pairs
 
         :param append: controls whether this returns a list of values or a single
@@ -776,12 +774,6 @@ last, after all sets and adds."""),
             if len(value) == 0:
                 # None means "delete this attribute"
                 value = None
-            if attr in self.params:
-                try:
-                   value = self.params[attr](value)
-                except errors.ValidationError, err:
-                    (name, error) = str(err.strerror).split(':')
-                    raise errors.ValidationError(name=attr, error=error)
             if append and attr in newdict:
                 if type(value) in (tuple,):
                     newdict[attr] += list(value)
@@ -885,12 +877,25 @@ last, after all sets and adds."""),
         # normalize all values
         changedattrs = setattrs | addattrs | delattrs
         for attr in changedattrs:
-            # remove duplicite and invalid values
-            entry_attrs[attr] = list(set([val for val in entry_attrs[attr] if val]))
-            if not entry_attrs[attr]:
-                entry_attrs[attr] = None
-            elif isinstance(entry_attrs[attr], (tuple, list)) and len(entry_attrs[attr]) == 1:
-                entry_attrs[attr] = entry_attrs[attr][0]
+            if attr in self.params:
+                # convert single-value params to scalars
+                if not self.params[attr].multivalue:
+                    if len(entry_attrs[attr]) == 1:
+                        entry_attrs[attr] = entry_attrs[attr][0]
+                    elif not entry_attrs[attr]:
+                        entry_attrs[attr] = None
+                    else:
+                        raise errors.OnlyOneValueAllowed(attr=attr)
+                # validate and convert params
+                entry_attrs[attr] = self.params[attr](entry_attrs[attr])
+            else:
+                # unknown attribute: remove duplicite and invalid values
+                entry_attrs[attr] = list(set([val for val in entry_attrs[attr] if val]))
+                if not entry_attrs[attr]:
+                    entry_attrs[attr] = None
+                elif isinstance(entry_attrs[attr], (tuple, list)) and len(entry_attrs[attr]) == 1:
+                    entry_attrs[attr] = entry_attrs[attr][0]
+
 
 class LDAPCreate(BaseLDAPCommand, crud.Create):
     """
-- 
1.7.7.6

From 7d85b3ec192347dc9e2f0bcf7407aa151029c773 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pviktori redhat com>
Date: Fri, 24 Feb 2012 09:14:19 -0500
Subject: [PATCH 17/17] Honor no_create and no_update flags with addattr &
 setattr

https://fedorahosted.org/freeipa/ticket/2408
---
 ipalib/errors.py           |   18 ++++++++++++++++++
 ipalib/plugins/baseldap.py |   20 +++++++++++++++++++-
 2 files changed, 37 insertions(+), 1 deletions(-)

diff --git a/ipalib/errors.py b/ipalib/errors.py
index bdc4a5e73ed8cbb7f0509b871a649d89352b7bd2..b7c08474d29cab6e3c71ed1c0ee071045e48df99 100644
--- a/ipalib/errors.py
+++ b/ipalib/errors.py
@@ -825,6 +825,24 @@ class PromptFailed(InvocationError):
     format = _('Could not get %(name)s interactively')
 
 
+class UnupdatableAttribute(InvocationError):
+    """
+    **3015** Raise when an attribute cannot be updated.
+    """
+
+    errno = 3015
+    format = _('Attribute %(attr)s may not be updated')
+
+
+class UncreatableAttribute(InvocationError):
+    """
+    **3015** Raise when an attribute cannot be specified on create.
+    """
+
+    errno = 3015
+    format = _('Attribute %(attr)s may not be specified when adding object')
+
+
 ##############################################################################
 # 4000 - 4999: Execution errors
 
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index 55d93eb28e3d9e41ca43a0cd04755d44c9f7240a..ceeb30da1bb63d92d2e8884a1ce7cb174f79542a 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -187,7 +187,6 @@ global_output_params = (
     ),
 )
 
-
 def validate_add_attribute(ugettext, attr):
     validate_attribute(ugettext, 'addattr', attr)
 
@@ -754,6 +753,10 @@ last, after all sets and adds."""),
                          exclude='webui',
                         )
 
+    # Param flag for disallowed attributes, e.g. no_update for Update
+    # Also set disallowed_attribute_error if used
+    disallowed_attribute_flag = None
+
     def _convert_2_dict(self, attrs, append=True):
         """
         Convert a string in the form of name/value pairs into a dictionary.
@@ -771,6 +774,15 @@ last, after all sets and adds."""),
             m = re.match("\s*(.*?)\s*=\s*(.*?)\s*$", a)
             attr = str(m.group(1)).lower()
             value = m.group(2)
+
+            # Disallow params marked by disallowed_attribute_flag
+            # Need to use the LDAPObject's params, not self's, because the
+            # CRUD classes filter their disallowed parameters out
+            params = self.obj.params
+            flag = self.disallowed_attribute_flag
+            if flag and (attr in params) and (flag in params[attr].flags):
+                raise self.disallowed_attribute_error(attr=attr)
+
             if len(value) == 0:
                 # None means "delete this attribute"
                 value = None
@@ -903,6 +915,9 @@ class LDAPCreate(BaseLDAPCommand, crud.Create):
     """
     takes_options = (BaseLDAPCommand.setattr_option, BaseLDAPCommand.addattr_option)
 
+    disallowed_attribute_flag = 'no_create'
+    disallowed_attribute_error = errors.UncreatableAttribute
+
     def get_args(self):
         #pylint: disable=E1003
         for key in self.obj.get_ancestor_primary_keys():
@@ -1182,6 +1197,9 @@ class LDAPUpdate(LDAPQuery, crud.Update):
 
     has_output_params = global_output_params
 
+    disallowed_attribute_flag = 'no_update'
+    disallowed_attribute_error = errors.UnupdatableAttribute
+
     def _get_rename_option(self):
         rdnparam = getattr(self.obj.params, self.obj.rdnattr)
         return rdnparam.clone_rename('rename',
-- 
1.7.7.6


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]