[CalendarServer-changes] [12244] twext/trunk/twext/who

source_changes at macosforge.org source_changes at macosforge.org
Wed Mar 12 11:17:02 PDT 2014


Revision: 12244
          http://trac.calendarserver.org//changeset/12244
Author:   wsanchez at apple.com
Date:     2014-01-06 15:22:43 -0800 (Mon, 06 Jan 2014)
Log Message:
-----------
Handle invalid directory record fields.

Modified Paths:
--------------
    twext/trunk/twext/who/directory.py
    twext/trunk/twext/who/idirectory.py
    twext/trunk/twext/who/opendirectory/_service.py

Modified: twext/trunk/twext/who/directory.py
===================================================================
--- twext/trunk/twext/who/directory.py	2014-01-06 22:03:14 UTC (rev 12243)
+++ twext/trunk/twext/who/directory.py	2014-01-06 23:22:43 UTC (rev 12244)
@@ -31,6 +31,7 @@
 from twisted.cred.credentials import DigestedCredentials
 
 from .idirectory import (
+    InvalidDirectoryRecordError,
     QueryNotSupportedError, NotAllowedError,
     FieldName, RecordType,
     IDirectoryService, IDirectoryRecord,
@@ -323,33 +324,40 @@
     def __init__(self, service, fields):
         for fieldName in self.requiredFields:
             if fieldName not in fields or not fields[fieldName]:
-                raise ValueError("{0} field is required.".format(fieldName))
+                raise InvalidDirectoryRecordError(
+                    "{0} field is required.".format(fieldName),
+                    fields
+                )
 
             if service.fieldName.isMultiValue(fieldName):
                 values = fields[fieldName]
                 for value in values:
                     if not value:
-                        raise ValueError(
-                            "{0} field must not be empty.".format(fieldName)
+                        raise InvalidDirectoryRecordError(
+                            "{0} field must not be empty.".format(fieldName),
+                            fields
                         )
 
         if (
             fields[FieldName.recordType] not in
             service.recordType.iterconstants()
         ):
-            raise ValueError(
+            raise InvalidDirectoryRecordError(
                 "Unknown record type: {0!r} is not in {1!r}.".format(
                     fields[FieldName.recordType],
                     tuple(service.recordType.iterconstants()),
-                )
+                ),
+                fields
             )
 
         def checkType(name, value):
             expectedType = service.fieldName.valueType(name)
             if not isinstance(value, expectedType):
-                raise TypeError(
-                    "Value {0!r} for field {1} is not of type {2}"
-                    .format(value, name, expectedType)
+                raise InvalidDirectoryRecordError(
+                    "Value {0!r} for field {1} is not of type {2}".format(
+                        value, name, expectedType
+                    ),
+                    fields
                 )
 
         # Normalize fields

Modified: twext/trunk/twext/who/idirectory.py
===================================================================
--- twext/trunk/twext/who/idirectory.py	2014-01-06 22:03:14 UTC (rev 12243)
+++ twext/trunk/twext/who/idirectory.py	2014-01-06 23:22:43 UTC (rev 12244)
@@ -23,6 +23,7 @@
     "DirectoryServiceError",
     "DirectoryConfigurationError",
     "DirectoryAvailabilityError",
+    "InvalidDirectoryRecordError",
     "UnknownRecordTypeError",
     "QueryNotSupportedError",
     "NoSuchRecordError",
@@ -68,6 +69,23 @@
 
 
 
+class InvalidDirectoryRecordError(DirectoryServiceError):
+    """
+    Invalid directory record.
+    """
+    def __init__(self, message, fields):
+        """
+        @param message: An error message.
+        @type message: string
+
+        @param fields: The fields that were used to attempt to build a record.
+        @type fields: L{dict}
+        """
+        super(InvalidDirectoryRecordError, self).__init__(message)
+        self.fields = fields
+
+
+
 class UnknownRecordTypeError(DirectoryServiceError):
     """
     Unknown record type.

Modified: twext/trunk/twext/who/opendirectory/_service.py
===================================================================
--- twext/trunk/twext/who/opendirectory/_service.py	2014-01-06 22:03:14 UTC (rev 12243)
+++ twext/trunk/twext/who/opendirectory/_service.py	2014-01-06 23:22:43 UTC (rev 12244)
@@ -30,7 +30,8 @@
 from twext.python.log import Logger
 
 from ..idirectory import (
-    DirectoryServiceError, QueryNotSupportedError,
+    DirectoryServiceError, DirectoryAvailabilityError,
+    InvalidDirectoryRecordError, QueryNotSupportedError,
     FieldName as BaseFieldName, RecordType as BaseRecordType,
     IPlaintextPasswordVerifier, IHTTPDigestVerifier,
 )
@@ -66,13 +67,17 @@
 
 
 
-class OpenDirectoryConnectionError(OpenDirectoryError):
+class OpenDirectoryConnectionError(DirectoryAvailabilityError):
     """
     OpenDirectory connection error.
     """
 
+    def __init__(self, message, odError=None):
+        super(OpenDirectoryConnectionError, self).__init__(message)
+        self.odError = odError
 
 
+
 class OpenDirectoryQueryError(OpenDirectoryError):
     """
     OpenDirectory query error.
@@ -346,6 +351,7 @@
             raise QueryNotSupportedError(
                 "Unknown match type: {0}".format(matchType)
             )
+        matchType = matchType.value
 
         if MatchFlags.caseInsensitive in iterFlags(expression.flags):
             caseInsensitive = 0x100
@@ -356,21 +362,25 @@
         maxResults = 0
 
         if expression.fieldName is self.fieldName.recordType:
-            recordTypes = ODRecordType.fromRecordType(expression.fieldValue).value
-            matchType = ODMatchType.all
+            recordTypes = ODRecordType.fromRecordType(
+                expression.fieldValue
+            ).value
+            matchType = ODMatchType.all.value
             queryAttribute = None
             queryValue = None
 
         else:
             recordTypes = [t.value for t in ODRecordType.iterconstants()]
-            queryAttribute = ODAttribute.fromFieldName(expression.fieldName).value
+            queryAttribute = ODAttribute.fromFieldName(
+                expression.fieldName
+            ).value
             queryValue = expression.fieldValue
 
         query, error = ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
             self.node,
             recordTypes,
             queryAttribute,
-            matchType.value | caseInsensitive,
+            matchType | caseInsensitive,
             queryValue,
             fetchAttributes,
             maxResults,
@@ -415,9 +425,23 @@
                 "Unable to execute OpenDirectory query", error
             ))
 
-        return succeed([DirectoryRecord(self, odr) for odr in odRecords])
+        result = []
+        for odRecord in odRecords:
+            try:
+                record = DirectoryRecord(self, odRecord)
+            except InvalidDirectoryRecordError as e:
+                self.log.error(
+                    "Invalid OpenDirectory record ({error}).  "
+                    "Fields: {error.fields}",
+                    error=e
+                )
+                continue
 
+            result.append(record)
 
+        return succeed(result)
+
+
     def recordsFromNonCompoundExpression(self, expression, records=None):
         if isinstance(expression, MatchExpression):
             try:
@@ -542,8 +566,15 @@
                 fields[fieldName] = values[0]
 
         # Set uid from guid
-        fields[service.fieldName.uid] = unicode(fields[service.fieldName.guid])
+        try:
+            guid = fields[service.fieldName.guid]
+        except KeyError:
+            raise InvalidDirectoryRecordError(
+                "GUID field is required.", fields
+            )
 
+        fields[service.fieldName.uid] = unicode(guid)
+
         super(DirectoryRecord, self).__init__(service, fields)
         self._odRecord = odRecord
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140312/b61580bc/attachment.html>


More information about the calendarserver-changes mailing list