[CalendarServer-changes] [1925] PyOpenDirectory/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Fri Sep 28 13:01:21 PDT 2007
Revision: 1925
http://trac.macosforge.org/projects/calendarserver/changeset/1925
Author: cdaboo at apple.com
Date: 2007-09-28 13:01:21 -0700 (Fri, 28 Sep 2007)
Log Message:
-----------
Merged branches/users/cdaboo/multiple-computer-records-1917 to trunk.
Modified Paths:
--------------
PyOpenDirectory/trunk/pysrc/opendirectory.py
PyOpenDirectory/trunk/src/CDirectoryService.cpp
PyOpenDirectory/trunk/src/CDirectoryService.h
PyOpenDirectory/trunk/src/PythonWrapper.cpp
PyOpenDirectory/trunk/test.py
PyOpenDirectory/trunk/test_auth.py
Modified: PyOpenDirectory/trunk/pysrc/opendirectory.py
===================================================================
--- PyOpenDirectory/trunk/pysrc/opendirectory.py 2007-09-28 18:09:43 UTC (rev 1924)
+++ PyOpenDirectory/trunk/pysrc/opendirectory.py 2007-09-28 20:01:21 UTC (rev 1925)
@@ -36,7 +36,7 @@
@param obj: C{object} the object obtained from an odInit call.
@param recordType: C{str} containing the OD record type to lookup.
@param attributes: C{list} containing the attributes to return for each record.
- @return: C{dict} containing a C{dict} of attributes for each record found,
+ @return: C{dict} containing a C{dict} of attributes for each record found,
or C{None} otherwise.
"""
@@ -51,7 +51,7 @@
@param casei: C{True} to do case-insenstive match, C{False} otherwise.
@param recordType: C{str} containing the OD record type to lookup.
@param attributes: C{list} containing the attributes to return for each record.
- @return: C{dict} containing a C{dict} of attributes for each record found,
+ @return: C{dict} containing a C{dict} of attributes for each record found,
or C{None} otherwise.
"""
@@ -64,10 +64,49 @@
@param casei: C{True} to do case-insenstive match, C{False} otherwise.
@param recordType: C{str} containing the OD record type to lookup.
@param attributes: C{list} containing the attributes to return for each record.
- @return: C{dict} containing a C{dict} of attributes for each record found,
+ @return: C{dict} containing a C{dict} of attributes for each record found,
or C{None} otherwise.
"""
+def listAllRecordsWithAttributes_list(obj, recordType, attributes):
+ """
+ List records in Open Directory, and return key attributes for each one.
+
+ @param obj: C{object} the object obtained from an odInit call.
+ @param recordType: C{str} containing the OD record type to lookup.
+ @param attributes: C{list} containing the attributes to return for each record.
+ @return: C{list} containing a C{list} of C{str} (record name) and C{dict} attributes
+ for each record found, or C{None} otherwise.
+ """
+
+def queryRecordsWithAttribute_list(obj, attr, value, matchType, casei, recordType, attributes):
+ """
+ List records in Open Directory matching specified attribute/value, and return key attributes for each one.
+
+ @param obj: C{object} the object obtained from an odInit call.
+ @param attr: C{str} containing the attribute to search.
+ @param value: C{str} containing the value to search for.
+ @param matchType: C{int} DS match type to use when searching.
+ @param casei: C{True} to do case-insenstive match, C{False} otherwise.
+ @param recordType: C{str} containing the OD record type to lookup.
+ @param attributes: C{list} containing the attributes to return for each record.
+ @return: C{list} containing a C{list} of C{str} (record name) and C{dict} attributes
+ for each record found, or C{None} otherwise.
+ """
+
+def queryRecordsWithAttributes_list(obj, compound, casei, recordType, attributes):
+ """
+ List records in Open Directory matching specified criteria, and return key attributes for each one.
+
+ @param obj: C{object} the object obtained from an odInit call.
+ @param compound: C{str} containing the compound search query to use.
+ @param casei: C{True} to do case-insenstive match, C{False} otherwise.
+ @param recordType: C{str} containing the OD record type to lookup.
+ @param attributes: C{list} containing the attributes to return for each record.
+ @return: C{list} containing a C{list} of C{str} (record name) and C{dict} attributes
+ for each record found, or C{None} otherwise.
+ """
+
def authenticateUserBasic(obj, guid, user, pswd):
"""
Authenticate a user with a password to Open Directory.
Modified: PyOpenDirectory/trunk/src/CDirectoryService.cpp
===================================================================
--- PyOpenDirectory/trunk/src/CDirectoryService.cpp 2007-09-28 18:09:43 UTC (rev 1924)
+++ PyOpenDirectory/trunk/src/CDirectoryService.cpp 2007-09-28 20:01:21 UTC (rev 1925)
@@ -85,11 +85,12 @@
//
// @param recordType: the record type to list.
// @param attributes: CFArray of CFString listing the attributes to return for each record.
-// @return: CFMutableDictionaryRef composed of CFMutableDictionaryRef of CFStringRef key and value entries
-// for each attribute/value requested in the record indexed by uid,
+// @return: CFMutableArrayRef composed of CFMutableArrayRef with a CFStringRef/CFMutableDictionaryRef tuple for
+// each record, where the CFStringRef is the record name and CFMutableDictionaryRef of CFStringRef key
+// and value entries for each attribute/value requested in the record indexed by uid,
// or NULL if it fails.
//
-CFMutableDictionaryRef CDirectoryService::ListAllRecordsWithAttributes(const char* recordType, CFArrayRef attributes)
+CFMutableArrayRef CDirectoryService::ListAllRecordsWithAttributes(const char* recordType, CFArrayRef attributes)
{
try
{
@@ -118,11 +119,12 @@
// @param casei: true if case-insensitive match is to be used, false otherwise.
// @param recordType: the record type to list.
// @param attributes: CFArray of CFString listing the attributes to return for each record.
-// @return: CFMutableDictionaryRef composed of CFMutableDictionaryRef of CFStringRef key and value entries
-// for each attribute/value requested in the record indexed by uid,
+// @return: CFMutableArrayRef composed of CFMutableArrayRef with a CFStringRef/CFMutableDictionaryRef tuple for
+// each record, where the CFStringRef is the record name and CFMutableDictionaryRef of CFStringRef key
+// and value entries for each attribute/value requested in the record indexed by uid,
// or NULL if it fails.
//
-CFMutableDictionaryRef CDirectoryService::QueryRecordsWithAttribute(const char* attr, const char* value, int matchType, bool casei, const char* recordType, CFArrayRef attributes)
+CFMutableArrayRef CDirectoryService::QueryRecordsWithAttribute(const char* attr, const char* value, int matchType, bool casei, const char* recordType, CFArrayRef attributes)
{
try
{
@@ -149,11 +151,12 @@
// @param casei: true if case-insensitive match is to be used, false otherwise.
// @param recordType: the record type to list.
// @param attributes: CFArray of CFString listing the attributes to return for each record.
-// @return: CFMutableDictionaryRef composed of CFMutableDictionaryRef of CFStringRef key and value entries
-// for each attribute/value requested in the record indexed by uid,
+// @return: CFMutableArrayRef composed of CFMutableArrayRef with a CFStringRef/CFMutableDictionaryRef tuple for
+// each record, where the CFStringRef is the record name and CFMutableDictionaryRef of CFStringRef key
+// and value entries for each attribute/value requested in the record indexed by uid,
// or NULL if it fails.
//
-CFMutableDictionaryRef CDirectoryService::QueryRecordsWithAttributes(const char* query, bool casei, const char* recordType, CFArrayRef attributes)
+CFMutableArrayRef CDirectoryService::QueryRecordsWithAttributes(const char* query, bool casei, const char* recordType, CFArrayRef attributes)
{
try
{
@@ -237,14 +240,16 @@
// @param type: the record type to check.
// @param names: a list of record names to target if NULL all records are matched.
// @param attrs: a list of attributes to return.
-// @return: CFMutableDictionaryRef composed of CFMutableDictionaryRef of CFStringRef key and value entries
-// for each attribute/value requested in the record indexed by uid,
+// @return: CFMutableArrayRef composed of CFMutableArrayRef with a CFStringRef/CFMutableDictionaryRef tuple for
+// each record, where the CFStringRef is the record name and CFMutableDictionaryRef of CFStringRef key
+// and value entries for each attribute/value requested in the record indexed by uid,
// or NULL if it fails.
//
-CFMutableDictionaryRef CDirectoryService::_ListAllRecordsWithAttributes(const char* type, CFArrayRef names, CFArrayRef attrs)
+CFMutableArrayRef CDirectoryService::_ListAllRecordsWithAttributes(const char* type, CFArrayRef names, CFArrayRef attrs)
{
- CFMutableDictionaryRef result = NULL;
- CFMutableDictionaryRef vresult = NULL;
+ CFMutableArrayRef result = NULL;
+ CFMutableArrayRef record_tuple = NULL;
+ CFMutableDictionaryRef record = NULL;
CFMutableArrayRef values = NULL;
tDataListPtr recNames = NULL;
tDataListPtr recTypes = NULL;
@@ -286,7 +291,7 @@
ThrowIfNULL(attrTypes);
BuildStringDataList(attrs, attrTypes);
- result = ::CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ result = ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
do
{
@@ -311,7 +316,7 @@
std::auto_ptr<char> recname(temp);
// Create a dictionary for the values
- vresult = ::CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ record = ::CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
// Look at each requested attribute and get one value
for(unsigned long j = 1; j <= pRecEntry->fRecordAttributeCount; j++)
@@ -342,7 +347,7 @@
::dsDeallocAttributeValueEntry(mDir, attributeValue);
attributeValue = NULL;
}
- ::CFDictionarySetValue(vresult, cfattrname.get(), values);
+ ::CFDictionarySetValue(record, cfattrname.get(), values);
::CFRelease(values);
values = NULL;
}
@@ -353,7 +358,7 @@
ThrowIfDSErr(::dsGetAttributeValue(mNode, mData, 1, attributeValueListRef, &attributeValue));
std::auto_ptr<char> data(CStringFromBuffer(&attributeValue->fAttributeValueData));
CFStringUtil strvalue(data.get());
- ::CFDictionarySetValue(vresult, cfattrname.get(), strvalue.get());
+ ::CFDictionarySetValue(record, cfattrname.get(), strvalue.get());
::dsDeallocAttributeValueEntry(mDir, attributeValue);
attributeValue = NULL;
}
@@ -365,12 +370,20 @@
attributeInfoPtr = NULL;
}
- // Add dictionary of values to result array
+ // Create tuple of record name and record values
CFStringUtil str(recname.get());
- ::CFDictionarySetValue(result, str.get(), vresult);
- ::CFRelease(vresult);
- vresult = NULL;
+ record_tuple = ::CFArrayCreateMutable(kCFAllocatorDefault, 2, &kCFTypeArrayCallBacks);
+ ::CFArrayAppendValue(record_tuple, str.get());
+ ::CFArrayAppendValue(record_tuple, record);
+ ::CFRelease(record);
+ record = NULL;
+
+ // Append tuple to results array
+ ::CFArrayAppendValue(result, record_tuple);
+ ::CFRelease(record_tuple);
+ record_tuple = NULL;
+
// Clean-up
::dsCloseAttributeList(attrListRef);
attrListRef = 0L;
@@ -426,11 +439,16 @@
::CFRelease(values);
values = NULL;
}
- if (vresult != NULL)
+ if (record != NULL)
{
- ::CFRelease(vresult);
- vresult = NULL;
+ ::CFRelease(record);
+ record = NULL;
}
+ if (record_tuple != NULL)
+ {
+ ::CFRelease(record_tuple);
+ record_tuple = NULL;
+ }
if (result != NULL)
{
::CFRelease(result);
@@ -453,14 +471,16 @@
// @param casei: true if case-insensitive match is to be used, false otherwise.
// @param type: the record type to check.
// @param attrs: a list of attributes to return.
-// @return: CFMutableDictionaryRef composed of CFMutableDictionaryRef of CFStringRef key and value entries
-// for each attribute/value requested in the record indexed by uid,
+// @return: CFMutableArrayRef composed of CFMutableArrayRef with a CFStringRef/CFMutableDictionaryRef tuple for
+// each record, where the CFStringRef is the record name and CFMutableDictionaryRef of CFStringRef key
+// and value entries for each attribute/value requested in the record indexed by uid,
// or NULL if it fails.
//
-CFMutableDictionaryRef CDirectoryService::_QueryRecordsWithAttributes(const char* attr, const char* value, int matchType, const char* compound, bool casei, const char* type, CFArrayRef attrs)
+CFMutableArrayRef CDirectoryService::_QueryRecordsWithAttributes(const char* attr, const char* value, int matchType, const char* compound, bool casei, const char* type, CFArrayRef attrs)
{
- CFMutableDictionaryRef result = NULL;
- CFMutableDictionaryRef vresult = NULL;
+ CFMutableArrayRef result = NULL;
+ CFMutableArrayRef record_tuple = NULL;
+ CFMutableDictionaryRef record = NULL;
CFMutableArrayRef values = NULL;
tDataNodePtr queryAttr = NULL;
tDataNodePtr queryValue = NULL;
@@ -520,7 +540,7 @@
ThrowIfNULL(attrTypes);
BuildStringDataList(attrs, attrTypes);
- result = ::CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ result = ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
do
{
@@ -545,7 +565,7 @@
std::auto_ptr<char> recname(temp);
// Create a dictionary for the values
- vresult = ::CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ record = ::CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
// Look at each requested attribute and get one value
for(unsigned long j = 1; j <= pRecEntry->fRecordAttributeCount; j++)
@@ -576,7 +596,7 @@
::dsDeallocAttributeValueEntry(mDir, attributeValue);
attributeValue = NULL;
}
- ::CFDictionarySetValue(vresult, cfattrname.get(), values);
+ ::CFDictionarySetValue(record, cfattrname.get(), values);
::CFRelease(values);
values = NULL;
}
@@ -587,7 +607,7 @@
ThrowIfDSErr(::dsGetAttributeValue(mNode, mData, 1, attributeValueListRef, &attributeValue));
std::auto_ptr<char> data(CStringFromBuffer(&attributeValue->fAttributeValueData));
CFStringUtil strvalue(data.get());
- ::CFDictionarySetValue(vresult, cfattrname.get(), strvalue.get());
+ ::CFDictionarySetValue(record, cfattrname.get(), strvalue.get());
::dsDeallocAttributeValueEntry(mDir, attributeValue);
attributeValue = NULL;
}
@@ -599,12 +619,20 @@
attributeInfoPtr = NULL;
}
- // Add dictionary of values to result array
+ // Create tuple of record name and record values
CFStringUtil str(recname.get());
- ::CFDictionarySetValue(result, str.get(), vresult);
- ::CFRelease(vresult);
- vresult = NULL;
+ record_tuple = ::CFArrayCreateMutable(kCFAllocatorDefault, 2, &kCFTypeArrayCallBacks);
+ ::CFArrayAppendValue(record_tuple, str.get());
+ ::CFArrayAppendValue(record_tuple, record);
+ ::CFRelease(record);
+ record = NULL;
+
+ // Append tuple to results array
+ ::CFArrayAppendValue(result, record_tuple);
+ ::CFRelease(record_tuple);
+ record_tuple = NULL;
+
// Clean-up
::dsCloseAttributeList(attrListRef);
attrListRef = 0L;
@@ -664,11 +692,16 @@
::CFRelease(values);
values = NULL;
}
- if (vresult != NULL)
+ if (record != NULL)
{
- ::CFRelease(vresult);
- vresult = NULL;
+ ::CFRelease(record);
+ record = NULL;
}
+ if (record_tuple != NULL)
+ {
+ ::CFRelease(record_tuple);
+ record_tuple = NULL;
+ }
if (result != NULL)
{
::CFRelease(result);
@@ -698,22 +731,20 @@
::CFArrayAppendValue(attrs, cfattr.get());
// First list the record for the current GUID and get its node.
- CFMutableDictionaryRef found = _QueryRecordsWithAttributes(kDS1AttrGeneratedUID, guid, eDSExact, NULL, false, kDSStdRecordTypeUsers, attrs);
+ CFMutableArrayRef found = _QueryRecordsWithAttributes(kDS1AttrGeneratedUID, guid, eDSExact, NULL, false, kDSStdRecordTypeUsers, attrs);
::CFRelease(attrs);
if (found == NULL)
return result;
// Must have only one result
- if (CFDictionaryGetCount(found) != 1)
+ if (CFArrayGetCount(found) != 1)
{
::CFRelease(found);
return result;
}
- // Now extract the returned data.
- const void* dictvalues[1] = {NULL};
- ::CFDictionaryGetKeysAndValues(found, NULL, &dictvalues[0]);
- CFDictionaryRef dictvalue = (CFDictionaryRef)dictvalues[0];
+ // Now extract the returned record data.
+ CFDictionaryRef dictvalue = (CFDictionaryRef)::CFArrayGetValueAtIndex((CFArrayRef)::CFArrayGetValueAtIndex(found, 0), 1);
if ((dictvalue == NULL) || (::CFDictionaryGetCount(dictvalue) == 0))
{
::CFRelease(found);
Modified: PyOpenDirectory/trunk/src/CDirectoryService.h
===================================================================
--- PyOpenDirectory/trunk/src/CDirectoryService.h 2007-09-28 18:09:43 UTC (rev 1924)
+++ PyOpenDirectory/trunk/src/CDirectoryService.h 2007-09-28 20:01:21 UTC (rev 1925)
@@ -32,9 +32,9 @@
CDirectoryService(const char* nodename);
~CDirectoryService();
- CFMutableDictionaryRef ListAllRecordsWithAttributes(const char* recordType, CFArrayRef attributes);
- CFMutableDictionaryRef QueryRecordsWithAttribute(const char* attr, const char* value, int matchType, bool casei, const char* recordType, CFArrayRef attributes);
- CFMutableDictionaryRef QueryRecordsWithAttributes(const char* query, bool casei, const char* recordType, CFArrayRef attributes);
+ CFMutableArrayRef ListAllRecordsWithAttributes(const char* recordType, CFArrayRef attributes);
+ CFMutableArrayRef QueryRecordsWithAttribute(const char* attr, const char* value, int matchType, bool casei, const char* recordType, CFArrayRef attributes);
+ CFMutableArrayRef QueryRecordsWithAttributes(const char* query, bool casei, const char* recordType, CFArrayRef attributes);
bool AuthenticateUserBasic(const char* guid, const char* user, const char* pswd, bool& result);
bool AuthenticateUserDigest(const char* guid, const char* user, const char* challenge, const char* response, const char* method, bool& result);
@@ -53,8 +53,8 @@
tDataBufferPtr mData;
UInt32 mDataSize;
- CFMutableDictionaryRef _ListAllRecordsWithAttributes(const char* type, CFArrayRef names, CFArrayRef attrs);
- CFMutableDictionaryRef _QueryRecordsWithAttributes(const char* attr, const char* value, int matchType, const char* compound, bool casei, const char* recordType, CFArrayRef attributes);
+ CFMutableArrayRef _ListAllRecordsWithAttributes(const char* type, CFArrayRef names, CFArrayRef attrs);
+ CFMutableArrayRef _QueryRecordsWithAttributes(const char* attr, const char* value, int matchType, const char* compound, bool casei, const char* recordType, CFArrayRef attributes);
CFStringRef CDirectoryService::AuthenticationGetNode(const char* guid);
bool NativeAuthenticationBasic(const char* guid, const char* user, const char* pswd);
Modified: PyOpenDirectory/trunk/src/PythonWrapper.cpp
===================================================================
--- PyOpenDirectory/trunk/src/PythonWrapper.cpp 2007-09-28 18:09:43 UTC (rev 1924)
+++ PyOpenDirectory/trunk/src/PythonWrapper.cpp 2007-09-28 20:01:21 UTC (rev 1925)
@@ -144,6 +144,78 @@
return result;
}
+// Utility function - not exposed to Python
+static PyObject* CFArrayStringDictionaryToPyList(CFArrayRef list)
+{
+ CFIndex lsize = (list != NULL) ? CFArrayGetCount(list) : 0;
+ if (lsize != 2)
+ return NULL;
+
+ PyObject* result = PyList_New(lsize);
+
+ CFStringRef str = (CFStringRef)CFArrayGetValueAtIndex(list, 0);
+ PyObject* pystr = CFStringToPyStr(str);
+ PyList_SetItem(result, 0, pystr);
+
+ CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(list, 1);
+ PyObject* pydict = CFDictionaryToPyDict(dict);
+ PyList_SetItem(result, 1, pydict);
+
+ return result;
+}
+
+// Utility function - not exposed to Python
+static PyObject* CFArrayArrayDictionaryToPyList(CFArrayRef list)
+{
+ CFIndex lsize = (list != NULL) ? CFArrayGetCount(list) : 0;
+
+ PyObject* result = PyList_New(lsize);
+ for(CFIndex i = 0, j = 0; i < lsize; i++)
+ {
+ CFArrayRef nested = (CFArrayRef)CFArrayGetValueAtIndex(list, i);
+ PyObject* pylist = CFArrayStringDictionaryToPyList(nested);
+ if (pylist != NULL)
+ {
+ PyList_SetItem(result, j++, pylist);
+ }
+ }
+
+ return result;
+}
+
+// Utility function - not exposed to Python
+static void CFArrayStringDictionaryToPyDict(CFArrayRef list, PyObject* result)
+{
+ CFIndex lsize = (list != NULL) ? CFArrayGetCount(list) : 0;
+ if (lsize != 2)
+ return;
+
+ CFStringRef str = (CFStringRef)CFArrayGetValueAtIndex(list, 0);
+ PyObject* pystrkey = CFStringToPyStr(str);
+
+ CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(list, 1);
+ PyObject* pydictvalue = CFDictionaryToPyDict(dict);
+
+ PyDict_SetItem(result, pystrkey, pydictvalue);
+ Py_DECREF(pystrkey);
+ Py_DECREF(pydictvalue);
+}
+
+// Utility function - not exposed to Python
+static PyObject* CFArrayArrayDictionaryToPyDict(CFArrayRef list)
+{
+ CFIndex lsize = (list != NULL) ? CFArrayGetCount(list) : 0;
+
+ PyObject* result = PyDict_New();
+ for(CFIndex i = 0; i < lsize; i++)
+ {
+ CFArrayRef nested = (CFArrayRef)CFArrayGetValueAtIndex(list, i);
+ CFArrayStringDictionaryToPyDict(nested, result);
+ }
+
+ return result;
+}
+
PyObject* ODException_class = NULL;
/*
@@ -193,9 +265,8 @@
@param obj: C{object} the object obtained from an odInit call.
@param recordType: C{str} containing the OD record type to lookup.
@param attributes: C{list} containing the attributes to return for each record.
- @return: C{dict} containing a C{dict} of attributes for each record found,
+ @return: C{dict} containing a C{dict} of attributes for each record found,
or C{None} otherwise.
- """
*/
extern "C" PyObject *listAllRecordsWithAttributes(PyObject *self, PyObject *args)
{
@@ -219,11 +290,11 @@
CDirectoryService* ds = static_cast<CDirectoryService*>(PyCObject_AsVoidPtr(pyds));
if (ds != NULL)
{
- CFMutableDictionaryRef dict = ds->ListAllRecordsWithAttributes(recordType, cfattributes);
- if (dict != NULL)
+ CFMutableArrayRef list = ds->ListAllRecordsWithAttributes(recordType, cfattributes);
+ if (list != NULL)
{
- PyObject* result = CFDictionaryDictionaryToPyDict(dict);
- CFRelease(dict);
+ PyObject* result = CFArrayArrayDictionaryToPyDict(list);
+ CFRelease(list);
CFRelease(cfattributes);
return result;
@@ -248,7 +319,7 @@
@param casei: C{True} to do case-insenstive match, C{False} otherwise.
@param recordType: C{str} containing the OD record type to lookup.
@param attributes: C{list} containing the attributes to return for each record.
- @return: C{dict} containing a C{dict} of attributes for each record found,
+ @return: C{dict} containing a C{dict} of attributes for each record found,
or C{None} otherwise.
"""
*/
@@ -282,11 +353,11 @@
CDirectoryService* ds = static_cast<CDirectoryService*>(PyCObject_AsVoidPtr(pyds));
if (ds != NULL)
{
- CFMutableDictionaryRef dict = ds->QueryRecordsWithAttribute(attr, value, matchType, casei, recordType, cfattributes);
- if (dict != NULL)
+ CFMutableArrayRef list = ds->QueryRecordsWithAttribute(attr, value, matchType, casei, recordType, cfattributes);
+ if (list != NULL)
{
- PyObject* result = CFDictionaryDictionaryToPyDict(dict);
- CFRelease(dict);
+ PyObject* result = CFArrayArrayDictionaryToPyDict(list);
+ CFRelease(list);
CFRelease(cfattributes);
return result;
@@ -309,7 +380,7 @@
@param casei: C{True} to do case-insenstive match, C{False} otherwise.
@param recordType: C{str} containing the OD record type to lookup.
@param attributes: C{list} containing the attributes to return for each record.
- @return: C{dict} containing a C{dict} of attributes for each record found,
+ @return: C{dict} containing a C{dict} of attributes for each record found,
or C{None} otherwise.
"""
*/
@@ -341,11 +412,11 @@
CDirectoryService* ds = static_cast<CDirectoryService*>(PyCObject_AsVoidPtr(pyds));
if (ds != NULL)
{
- CFMutableDictionaryRef dict = ds->QueryRecordsWithAttributes(query, casei, recordType, cfattributes);
- if (dict != NULL)
+ CFMutableArrayRef list = ds->QueryRecordsWithAttributes(query, casei, recordType, cfattributes);
+ if (list != NULL)
{
- PyObject* result = CFDictionaryDictionaryToPyDict(dict);
- CFRelease(dict);
+ PyObject* result = CFArrayArrayDictionaryToPyDict(list);
+ CFRelease(list);
CFRelease(cfattributes);
return result;
@@ -359,6 +430,179 @@
}
/*
+def listAllRecordsWithAttributes_list(obj, recordType, attributes):
+ """
+ List records in Open Directory, and return key attributes for each one.
+
+ @param obj: C{object} the object obtained from an odInit call.
+ @param recordType: C{str} containing the OD record type to lookup.
+ @param attributes: C{list} containing the attributes to return for each record.
+ @return: C{list} containing a C{list} of C{str} (record name) and C{dict} attributes
+ for each record found, or C{None} otherwise.
+ """
+ */
+extern "C" PyObject *listAllRecordsWithAttributes_list(PyObject *self, PyObject *args)
+{
+ PyObject* pyds;
+ const char* recordType;
+ PyObject* attributes;
+ if (!PyArg_ParseTuple(args, "OsO", &pyds, &recordType, &attributes) || !PyCObject_Check(pyds) || !PyList_Check(attributes))
+ {
+ PyErr_SetObject(ODException_class, Py_BuildValue("((s:i))", "DirectoryServices listAllRecordsWithAttributes: could not parse arguments", 0));
+ return NULL;
+ }
+
+ // Convert list to CFArray of CFString
+ CFArrayRef cfattributes = PyListToCFArray(attributes);
+ if (cfattributes == NULL)
+ {
+ PyErr_SetObject(ODException_class, Py_BuildValue("((s:i))", "DirectoryServices listAllRecordsWithAttributes: could not parse attributes list", 0));
+ return NULL;
+ }
+
+ CDirectoryService* ds = static_cast<CDirectoryService*>(PyCObject_AsVoidPtr(pyds));
+ if (ds != NULL)
+ {
+ CFMutableArrayRef list = ds->ListAllRecordsWithAttributes(recordType, cfattributes);
+ if (list != NULL)
+ {
+ PyObject* result = CFArrayArrayDictionaryToPyList(list);
+ CFRelease(list);
+ CFRelease(cfattributes);
+
+ return result;
+ }
+ }
+ else
+ PyErr_SetObject(ODException_class, Py_BuildValue("((s:i))", "DirectoryServices listAllRecordsWithAttributes: invalid directory service argument", 0));
+
+ CFRelease(cfattributes);
+ return NULL;
+}
+
+/*
+def queryRecordsWithAttribute_list(obj, attr, value, matchType, casei, recordType, attributes):
+ """
+ List records in Open Directory matching specified attribute and value, and return key attributes for each one.
+
+ @param obj: C{object} the object obtained from an odInit call.
+ @param attr: C{str} for the attribute to query.
+ @param value: C{str} for the attribute value to query.
+ @param matchType: C{int} DS match type to use when searching.
+ @param casei: C{True} to do case-insenstive match, C{False} otherwise.
+ @param recordType: C{str} containing the OD record type to lookup.
+ @param attributes: C{list} containing the attributes to return for each record.
+ @return: C{list} containing a C{list} of C{str} (record name) and C{dict} attributes
+ for each record found, or C{None} otherwise.
+ """
+ */
+extern "C" PyObject *queryRecordsWithAttribute_list(PyObject *self, PyObject *args)
+{
+ PyObject* pyds;
+ const char* attr;
+ const char* value;
+ int matchType;
+ PyObject* caseio;
+ bool casei;
+ const char* recordType;
+ PyObject* attributes;
+ if (!PyArg_ParseTuple(args, "OssiOsO", &pyds, &attr, &value, &matchType, &caseio, &recordType, &attributes) ||
+ !PyCObject_Check(pyds) || !PyBool_Check(caseio) || !PyList_Check(attributes))
+ {
+ PyErr_SetObject(ODException_class, Py_BuildValue("((s:i))", "DirectoryServices queryRecordsWithAttributes: could not parse arguments", 0));
+ return NULL;
+ }
+
+ casei = (caseio == Py_True);
+
+ // Convert list to CFArray of CFString
+ CFArrayRef cfattributes = PyListToCFArray(attributes);
+ if (cfattributes == NULL)
+ {
+ PyErr_SetObject(ODException_class, Py_BuildValue("((s:i))", "DirectoryServices queryRecordsWithAttributes: could not parse attributes list", 0));
+ return NULL;
+ }
+
+ CDirectoryService* ds = static_cast<CDirectoryService*>(PyCObject_AsVoidPtr(pyds));
+ if (ds != NULL)
+ {
+ CFMutableArrayRef list = ds->QueryRecordsWithAttribute(attr, value, matchType, casei, recordType, cfattributes);
+ if (list != NULL)
+ {
+ PyObject* result = CFArrayArrayDictionaryToPyList(list);
+ CFRelease(list);
+ CFRelease(cfattributes);
+
+ return result;
+ }
+ }
+ else
+ PyErr_SetObject(ODException_class, Py_BuildValue("((s:i))", "DirectoryServices queryRecordsWithAttributes: invalid directory service argument", 0));
+
+ CFRelease(cfattributes);
+ return NULL;
+}
+
+/*
+def queryRecordsWithAttributes_list(obj, query, casei, recordType, attributes):
+ """
+ List records in Open Directory matching specified compound query, and return key attributes for each one.
+
+ @param obj: C{object} the object obtained from an odInit call.
+ @param query: C{str} the compound query string.
+ @param casei: C{True} to do case-insenstive match, C{False} otherwise.
+ @param recordType: C{str} containing the OD record type to lookup.
+ @param attributes: C{list} containing the attributes to return for each record.
+ @return: C{list} containing a C{list} of C{str} (record name) and C{dict} attributes
+ for each record found, or C{None} otherwise.
+ """
+ */
+extern "C" PyObject *queryRecordsWithAttributes_list(PyObject *self, PyObject *args)
+{
+ PyObject* pyds;
+ const char* query;
+ PyObject* caseio;
+ bool casei;
+ const char* recordType;
+ PyObject* attributes;
+ if (!PyArg_ParseTuple(args, "OsOsO", &pyds, &query, &caseio, &recordType, &attributes) ||
+ !PyCObject_Check(pyds) || !PyBool_Check(caseio) || !PyList_Check(attributes))
+ {
+ PyErr_SetObject(ODException_class, Py_BuildValue("((s:i))", "DirectoryServices queryRecordsWithAttributes: could not parse arguments", 0));
+ return NULL;
+ }
+
+ casei = (caseio == Py_True);
+
+ // Convert list to CFArray of CFString
+ CFArrayRef cfattributes = PyListToCFArray(attributes);
+ if (cfattributes == NULL)
+ {
+ PyErr_SetObject(ODException_class, Py_BuildValue("((s:i))", "DirectoryServices queryRecordsWithAttributes: could not parse attributes list", 0));
+ return NULL;
+ }
+
+ CDirectoryService* ds = static_cast<CDirectoryService*>(PyCObject_AsVoidPtr(pyds));
+ if (ds != NULL)
+ {
+ CFMutableArrayRef list = ds->QueryRecordsWithAttributes(query, casei, recordType, cfattributes);
+ if (list != NULL)
+ {
+ PyObject* result = CFArrayArrayDictionaryToPyList(list);
+ CFRelease(list);
+ CFRelease(cfattributes);
+
+ return result;
+ }
+ }
+ else
+ PyErr_SetObject(ODException_class, Py_BuildValue("((s:i))", "DirectoryServices queryRecordsWithAttributes: invalid directory service argument", 0));
+
+ CFRelease(cfattributes);
+ return NULL;
+}
+
+/*
def authenticateUserBasic(obj, guid, user, pswd):
"""
Authenticate a user with a password to Open Directory.
@@ -455,6 +699,12 @@
"List records in Open Directory matching specified attribute/value, and return key attributes for each one."},
{"queryRecordsWithAttributes", queryRecordsWithAttributes, METH_VARARGS,
"List records in Open Directory matching specified criteria, and return key attributes for each one."},
+ {"listAllRecordsWithAttributes_list", listAllRecordsWithAttributes_list, METH_VARARGS,
+ "List all records of the specified type in Open Directory, returning requested attributes."},
+ {"queryRecordsWithAttribute_list", queryRecordsWithAttribute_list, METH_VARARGS,
+ "List records in Open Directory matching specified attribute/value, and return key attributes for each one."},
+ {"queryRecordsWithAttributes_list", queryRecordsWithAttributes_list, METH_VARARGS,
+ "List records in Open Directory matching specified criteria, and return key attributes for each one."},
{"authenticateUserBasic", authenticateUserBasic, METH_VARARGS,
"Authenticate a user with a password to Open Directory using plain text authentication."},
{"authenticateUserDigest", authenticateUserDigest, METH_VARARGS,
Modified: PyOpenDirectory/trunk/test.py
===================================================================
--- PyOpenDirectory/trunk/test.py 2007-09-28 18:09:43 UTC (rev 1924)
+++ PyOpenDirectory/trunk/test.py 2007-09-28 20:01:21 UTC (rev 1925)
@@ -149,23 +149,148 @@
[dsattributes.kDS1AttrGeneratedUID, dsattributes.kDS1AttrDistinguishedName,]
)
+ def listUsers_list():
+ d = opendirectory.listAllRecordsWithAttributes_list(ref, dsattributes.kDSStdRecordTypeUsers,
+ [dsattributes.kDS1AttrGeneratedUID, dsattributes.kDS1AttrDistinguishedName,])
+ if d is None:
+ print "Failed to list users"
+ else:
+ d.sort(cmp=lambda x, y: x[0] < y[0])
+ print "\nlistUsers_list number of results = %d" % (len(d),)
+ for name, record in d:
+ print "Name: %s" % name
+ print "dict: %s" % str(record)
+
+ def listGroups_list():
+ d = opendirectory.listAllRecordsWithAttributes_list(ref, dsattributes.kDSStdRecordTypeGroups,
+ [dsattributes.kDS1AttrGeneratedUID, dsattributes.kDSNAttrGroupMembers,])
+ if d is None:
+ print "Failed to list groups"
+ else:
+ d.sort(cmp=lambda x, y: x[0] < y[0])
+ print "\nlistGroups_list number of results = %d" % (len(d),)
+ for name, record in d:
+ print "Name: %s" % name
+ print "dict: %s" % str(record)
+
+ def listComputers_list():
+ d = opendirectory.listAllRecordsWithAttributes_list(ref, dsattributes.kDSStdRecordTypeComputers,
+ [dsattributes.kDS1AttrGeneratedUID, dsattributes.kDS1AttrXMLPlist,])
+ if d is None:
+ print "Failed to list computers"
+ else:
+ d.sort(cmp=lambda x, y: x[0] < y[0])
+ print "\nlistComputers_list number of results = %d" % (len(d),)
+ for name, record in d:
+ print "Name: %s" % name
+ print "dict: %s" % str(record)
+
+ def querySimple_list(title, attr, value, matchType, casei, recordType, attrs):
+ d = opendirectory.queryRecordsWithAttribute_list(
+ ref,
+ attr,
+ value,
+ matchType,
+ casei,
+ recordType,
+ attrs
+ )
+ if d is None:
+ print "Failed to query users"
+ else:
+ d.sort(cmp=lambda x, y: x[0] < y[0])
+ print "\n%s number of results = %d" % (title, len(d),)
+ for name, record in d:
+ print "Name: %s" % name
+ print "dict: %s" % str(record)
+
+ def queryCompound_list(title, compound, casei, recordType, attrs):
+ d = opendirectory.queryRecordsWithAttributes_list(
+ ref,
+ compound,
+ casei,
+ recordType,
+ attrs
+ )
+ if d is None:
+ print "Failed to query users"
+ else:
+ d.sort(cmp=lambda x, y: x[0] < y[0])
+ print "\n%s number of results = %d" % (title, len(d),)
+ for name, record in d:
+ print "Name: %s" % name
+ print "dict: %s" % str(record)
+
+ def queryUsers_list():
+ querySimple_list(
+ "queryUsers_list",
+ dsattributes.kDS1AttrFirstName,
+ "cyrus",
+ dsattributes.eDSExact,
+ True,
+ dsattributes.kDSStdRecordTypeUsers,
+ [dsattributes.kDS1AttrGeneratedUID, dsattributes.kDS1AttrDistinguishedName,]
+ )
+
+ def queryUsersCompoundOr_list():
+ queryCompound_list(
+ "queryUsersCompoundOr_list",
+ expression(expression.OR,
+ (match(dsattributes.kDS1AttrFirstName, "chris", dsattributes.eDSContains),
+ match(dsattributes.kDS1AttrLastName, "roy", dsattributes.eDSContains))).generate(),
+ False,
+ dsattributes.kDSStdRecordTypeUsers,
+ [dsattributes.kDS1AttrGeneratedUID, dsattributes.kDS1AttrDistinguishedName,]
+ )
+
+ def queryUsersCompoundOrExact_list():
+ queryCompound_list(
+ "queryUsersCompoundOrExact_list",
+ expression(expression.OR,
+ (match(dsattributes.kDS1AttrFirstName, "chris", dsattributes.eDSExact),
+ match(dsattributes.kDS1AttrLastName, "roy", dsattributes.eDSExact))).generate(),
+ False,
+ dsattributes.kDSStdRecordTypeUsers,
+ [dsattributes.kDS1AttrGeneratedUID, dsattributes.kDS1AttrDistinguishedName,]
+ )
+
+ def queryUsersCompoundAnd_list():
+ queryCompound_list(
+ "queryUsersCompoundAnd_list",
+ expression(expression.AND,
+ (match(dsattributes.kDS1AttrFirstName, "chris", dsattributes.eDSContains),
+ match(dsattributes.kDS1AttrLastName, "roy", dsattributes.eDSContains))).generate(),
+ True,
+ dsattributes.kDSStdRecordTypeUsers,
+ [dsattributes.kDS1AttrGeneratedUID, dsattributes.kDS1AttrDistinguishedName,]
+ )
+
def authentciateBasic():
if opendirectory.authenticateUserBasic(ref, "gooeyed", "test", "test"):
print "Authenticated user"
else:
print "Failed to authenticate user"
- #listUsers()
- #listGroups()
- #listComputers()
+ listUsers()
+ listGroups()
+ listComputers()
queryUsers()
queryUsersCompoundOr()
queryUsersCompoundOrExact()
queryUsersCompoundAnd()
+ listUsers_list()
+ listGroups_list()
+ listComputers_list()
+ queryUsers_list()
+ queryUsersCompoundOr_list()
+ queryUsersCompoundOrExact_list()
+ queryUsersCompoundAnd_list()
#authentciateBasic()
ref = None
except opendirectory.ODError, ex:
print ex
+except Exception, e:
+ print e
print "Done."
Modified: PyOpenDirectory/trunk/test_auth.py
===================================================================
--- PyOpenDirectory/trunk/test_auth.py 2007-09-28 18:09:43 UTC (rev 1924)
+++ PyOpenDirectory/trunk/test_auth.py 2007-09-28 20:01:21 UTC (rev 1925)
@@ -123,7 +123,7 @@
False,
dsattributes.kDSStdRecordTypeUsers,
[dsattributes.kDS1AttrGeneratedUID])
- guid = result[username][dsattributes.kDS1AttrGeneratedUID]
+ guid = result[0][1][dsattributes.kDS1AttrGeneratedUID]
expected = calcResponse(
calcHA1(algorithm, username, realm, password, nonce, cnonce),
@@ -173,7 +173,7 @@
False,
dsattributes.kDSStdRecordTypeUsers,
[dsattributes.kDS1AttrGeneratedUID])
- guid = result[username][dsattributes.kDS1AttrGeneratedUID]
+ guid = result[0][1][dsattributes.kDS1AttrGeneratedUID]
for x in xrange(attempts):
success = opendirectory.authenticateUserBasic(
@@ -196,6 +196,4 @@
doAuthBasic(user, pswd)
doAuthDigest(user, pswd, None, "md5")
-#doAuth(user, pswd, "auth", "md5")
-#doAuth(user, pswd, "auth", "md5-sess")
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070928/a65f4302/attachment.html
More information about the calendarserver-changes
mailing list