[CalendarServer-changes] [1951] PyOpenDirectory/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Oct 10 11:50:28 PDT 2007


Revision: 1951
          http://trac.macosforge.org/projects/calendarserver/changeset/1951
Author:   cdaboo at apple.com
Date:     2007-10-10 11:50:28 -0700 (Wed, 10 Oct 2007)

Log Message:
-----------
Eliminate a directory query on each authentication. To do authentication we need to know the directory node, and
previously we looked up the user guid to get that. Now we require the node to be passed in as an argument rather
than the guid. So the guid->node query can be eliminated.

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_auth.py

Modified: PyOpenDirectory/trunk/pysrc/opendirectory.py
===================================================================
--- PyOpenDirectory/trunk/pysrc/opendirectory.py	2007-10-10 15:53:39 UTC (rev 1950)
+++ PyOpenDirectory/trunk/pysrc/opendirectory.py	2007-10-10 18:50:28 UTC (rev 1951)
@@ -76,7 +76,7 @@
     @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.
+        for each record found, or C{None} otherwise.
     """
 
 def queryRecordsWithAttribute_list(obj, attr, value, matchType, casei, recordType, attributes):
@@ -91,7 +91,7 @@
     @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.
+        for each record found, or C{None} otherwise.
     """
 
 def queryRecordsWithAttributes_list(obj, compound, casei, recordType, attributes):
@@ -104,26 +104,26 @@
     @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.
+        for each record found, or C{None} otherwise.
     """
 
-def authenticateUserBasic(obj, guid, user, pswd):
+def authenticateUserBasic(obj, nodename, user, pswd):
     """
     Authenticate a user with a password to Open Directory.
     
     @param obj: C{object} the object obtained from an odInit call.
-    @param guid: C{str} the GUID for the record to check.
+    @param nodename: C{str} the directory nodename for the record to check.
     @param user: C{str} the user identifier/directory record name to check.
     @param pswd: C{str} containing the password to check.
     @return: C{True} if the user was found, C{False} otherwise.
     """
 
-def authenticateUserDigest(obj, guid, user, challenge, response, method):
+def authenticateUserDigest(obj, nodename, user, challenge, response, method):
     """
     Authenticate using HTTP Digest credentials to Open Directory.
     
     @param obj: C{object} the object obtained from an odInit call.
-    @param guid: C{str} the GUID for the record to check.
+    @param nodename: C{str} the directory nodename for the record to check.
     @param user: C{str} the user identifier/directory record name to check.
     @param challenge: C{str} the HTTP challenge sent to the client.
     @param response: C{str} the HTTP response sent from the client.
@@ -131,7 +131,7 @@
     @return: C{True} if the user was found, C{False} otherwise.
     """
 
-class ODError(exception):
+class ODError(Exception):
     """
     Exceptions from DirectoryServices errors.
     """

Modified: PyOpenDirectory/trunk/src/CDirectoryService.cpp
===================================================================
--- PyOpenDirectory/trunk/src/CDirectoryService.cpp	2007-10-10 15:53:39 UTC (rev 1950)
+++ PyOpenDirectory/trunk/src/CDirectoryService.cpp	2007-10-10 18:50:28 UTC (rev 1951)
@@ -179,16 +179,16 @@
 // 
 // Authenticate a user to the directory using plain text credentials.
 //
-// @param guid: the GUID for the user record.
+// @param nodename: the directory nodename for the user record.
 // @param user: the uid of the user.
 // @param pswd: the plain text password to authenticate with.
 // @return: true if authentication succeeds, false otherwise.
 //
-bool CDirectoryService::AuthenticateUserBasic(const char* guid, const char* user, const char* pswd, bool& result)
+bool CDirectoryService::AuthenticateUserBasic(const char* nodename, const char* user, const char* pswd, bool& result)
 {
 	try
 	{
-		result = NativeAuthenticationBasic(guid, user, pswd);
+		result = NativeAuthenticationBasicToNode(nodename, user, pswd);
 		return true;
 	}
 	catch(SDirectoryServiceException& dserror)
@@ -207,16 +207,16 @@
 // 
 // Authenticate a user to the directory using HTTP DIGEST credentials.
 //
-// @param guid: the GUID for the user record.
+// @param nodename: the directory nodename for the user record.
 // @param challenge: HTTP challenge sent by server.
 // @param response: HTTP response sent by client.
 // @return: true if authentication succeeds, false otherwise.
 //
-bool CDirectoryService::AuthenticateUserDigest(const char* guid, const char* user, const char* challenge, const char* response, const char* method, bool& result)
+bool CDirectoryService::AuthenticateUserDigest(const char* nodename, const char* user, const char* challenge, const char* response, const char* method, bool& result)
 {
 	try
 	{
-		result = NativeAuthenticationDigest(guid, user, challenge, response, method);
+		result = NativeAuthenticationDigestToNode(nodename, user, challenge, response, method);
 		return true;
 	}
 	catch(SDirectoryServiceException& dserror)
@@ -713,85 +713,6 @@
 	return result;
 }
 
-// AuthenticationGetNode
-// 
-// Get the node associated with the user we want to authenticate.
-//
-// @param guid: the GUID for the user record.
-// @return: CFStringUtil for node name.
-//
-CFStringRef CDirectoryService::AuthenticationGetNode(const char* guid)
-{
-	// We need to find the 'native' node for the specified record guid as the current node
-	// may not support this user's authentication directly.
-	CFStringRef result = NULL;
-	
-	CFMutableArrayRef attrs = ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-	CFStringUtil cfattr(kDSNAttrMetaNodeLocation);
-	::CFArrayAppendValue(attrs, cfattr.get());
-	
-	// First list the record for the current GUID and get its node.
-	CFMutableArrayRef found = _QueryRecordsWithAttributes(kDS1AttrGeneratedUID, guid, eDSExact, NULL, false, kDSStdRecordTypeUsers, attrs);
-	::CFRelease(attrs);
-	if (found == NULL)
-		return result;
-
-	// Must have only one result
-	if (CFArrayGetCount(found) != 1)
-	{
-		::CFRelease(found);
-		return result;
-	}
-
-	// Now extract the returned record data.
-	CFDictionaryRef dictvalue = (CFDictionaryRef)::CFArrayGetValueAtIndex((CFArrayRef)::CFArrayGetValueAtIndex(found, 0), 1);
-	if ((dictvalue == NULL) || (::CFDictionaryGetCount(dictvalue) == 0))
-	{
-		::CFRelease(found);
-		return result;
-	}
-	const void* value = ::CFDictionaryGetValue(dictvalue, cfattr.get());
-
-	// The dictionary value may be a string or a list
-	if (::CFGetTypeID((CFTypeRef)value) == ::CFStringGetTypeID())
-	{
-		result = (CFStringRef)value;
-	}
-	else if(::CFGetTypeID((CFTypeRef)value) == ::CFArrayGetTypeID())
-	{
-		CFArrayRef arrayvalue = (CFArrayRef)value;
-		if (::CFArrayGetCount(arrayvalue) == 0)
-			return result;
-		result = (CFStringRef)CFArrayGetValueAtIndex(arrayvalue, 0);
-	}
-
-	::CFRetain(result);
-	::CFRelease(found);
-	return result;
-}
-
-// NativeAuthenticationBasic
-// 
-// Authenticate a user to the directory.
-//
-// @param guid: the GUID for the user record.
-// @param user: the uid of the user.
-// @param pswd: the plain text password to authenticate with.
-// @return: true if authentication succeeds, false otherwise.
-//
-bool CDirectoryService::NativeAuthenticationBasic(const char* guid, const char* user, const char* pswd)
-{
-	// We need to find the 'native' node for the specifies user as the current node
-	// made not support this user's authentication directly.
-	
-	CFStringRef result = AuthenticationGetNode(guid);
-	if (result == NULL)
-		return false;
-	CFStringUtil cfvalue(result);
-	::CFRelease(result);
-	return NativeAuthenticationBasicToNode(cfvalue.temp_str(), user, pswd);
-}
-
 // NativeAuthenticationBasicToNode
 // 
 // Authenticate a user to the directory.
@@ -886,30 +807,6 @@
     return result;
 }
 
-// NativeAuthenticationDigest
-// 
-// Authenticate a user to the directory.
-//
-// @param guid: the GUID for the user record.
-// @param user: the uid of the user.
-// @param challenge: the server challenge.
-// @param response: the client response.
-// @param method: the HTTP method.
-// @return: true if authentication succeeds, false otherwise.
-//
-bool CDirectoryService::NativeAuthenticationDigest(const char* guid, const char* user, const char* challenge, const char* response, const char* method)
-{
-	// We need to find the 'native' node for the specifies user as the current node
-	// made not support this user's authentication directly.
-	
-	CFStringRef result = AuthenticationGetNode(guid);
-	if (result == NULL)
-		return false;
-	CFStringUtil cfvalue(result);
-	::CFRelease(result);
-	return NativeAuthenticationDigestToNode(cfvalue.temp_str(), user, challenge, response, method);
-}
-
 // NativeAuthenticationDigestToNode
 // 
 // Authenticate a user to the directory.

Modified: PyOpenDirectory/trunk/src/CDirectoryService.h
===================================================================
--- PyOpenDirectory/trunk/src/CDirectoryService.h	2007-10-10 15:53:39 UTC (rev 1950)
+++ PyOpenDirectory/trunk/src/CDirectoryService.h	2007-10-10 18:50:28 UTC (rev 1951)
@@ -36,8 +36,8 @@
 	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);
+	bool AuthenticateUserBasic(const char* nodename, const char* user, const char* pswd, bool& result);
+	bool AuthenticateUserDigest(const char* nodename, const char* user, const char* challenge, const char* response, const char* method, bool& result);
 	
 private:
 
@@ -56,10 +56,7 @@
 	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);
 	bool NativeAuthenticationBasicToNode(const char* nodename, const char* user, const char* pswd);
-	bool NativeAuthenticationDigest(const char* guid, const char* user, const char* challenge, const char* response, const char* method);
 	bool NativeAuthenticationDigestToNode(const char* nodename, const char* user, const char* challenge, const char* response, const char* method);
 	
 	void OpenService();

Modified: PyOpenDirectory/trunk/src/PythonWrapper.cpp
===================================================================
--- PyOpenDirectory/trunk/src/PythonWrapper.cpp	2007-10-10 15:53:39 UTC (rev 1950)
+++ PyOpenDirectory/trunk/src/PythonWrapper.cpp	2007-10-10 18:50:28 UTC (rev 1951)
@@ -603,12 +603,12 @@
 }
 
 /*
-def authenticateUserBasic(obj, guid, user, pswd):
+def authenticateUserBasic(obj, nodename, user, pswd):
 	"""
 	Authenticate a user with a password to Open Directory.
 	
 	@param obj: C{object} the object obtained from an odInit call.
-    @param guid: C{str} the GUID for the record to check.
+    @param nodename: C{str} the directory nodename for the record to check.
     @param user: C{str} the user identifier/directory record name to check.
 	@param pswd: C{str} containing the password to check.
 	@return: C{True} if the user was found, C{False} otherwise.
@@ -617,10 +617,10 @@
 extern "C" PyObject *authenticateUserBasic(PyObject *self, PyObject *args)
 {
 	PyObject* pyds;
-	const char* guid;
+	const char* nodename;
 	const char* user;
 	const char* pswd;
-    if (!PyArg_ParseTuple(args, "Osss", &pyds, &guid, &user, &pswd) || !PyCObject_Check(pyds))
+    if (!PyArg_ParseTuple(args, "Osss", &pyds, &nodename, &user, &pswd) || !PyCObject_Check(pyds))
     {
 		PyErr_SetObject(ODException_class, Py_BuildValue("((s:i))", "DirectoryServices authenticateUserBasic: could not parse arguments", 0));		
         return NULL;
@@ -630,7 +630,7 @@
 	if (ds != NULL)
 	{
 		bool result = false;
-		if (ds->AuthenticateUserBasic(guid, user, pswd, result))
+		if (ds->AuthenticateUserBasic(nodename, user, pswd, result))
 		{
 			if (result)
 				Py_RETURN_TRUE;
@@ -650,7 +650,7 @@
     Authenticate using HTTP Digest credentials to Open Directory.
     
     @param obj: C{object} the object obtained from an odInit call.
-    @param guid: C{str} the GUID for the record to check.
+    @param nodename: C{str} the directory nodename for the record to check.
 	@param user: C{str} the user identifier/directory record name to check.
     @param challenge: C{str} the HTTP challenge sent to the client.
     @param response: C{str} the HTTP response sent from the client.
@@ -661,12 +661,12 @@
 extern "C" PyObject *authenticateUserDigest(PyObject *self, PyObject *args)
 {
 	PyObject* pyds;
-	const char* guid;
+	const char* nodename;
 	const char* user;
 	const char* challenge;
 	const char* response;
 	const char* method;
-    if (!PyArg_ParseTuple(args, "Osssss", &pyds, &guid, &user, &challenge, &response, &method) || !PyCObject_Check(pyds))
+    if (!PyArg_ParseTuple(args, "Osssss", &pyds, &nodename, &user, &challenge, &response, &method) || !PyCObject_Check(pyds))
     {
 		PyErr_SetObject(ODException_class, Py_BuildValue("((s:i))", "DirectoryServices authenticateUserDigest: could not parse arguments", 0));		
         return NULL;
@@ -676,7 +676,7 @@
 	if (ds != NULL)
 	{
 		bool result = false;
-		if (ds->AuthenticateUserDigest(guid, user, challenge, response, method, result))
+		if (ds->AuthenticateUserDigest(nodename, user, challenge, response, method, result))
 		{
 			if (result)
 				Py_RETURN_TRUE;

Modified: PyOpenDirectory/trunk/test_auth.py
===================================================================
--- PyOpenDirectory/trunk/test_auth.py	2007-10-10 15:53:39 UTC (rev 1950)
+++ PyOpenDirectory/trunk/test_auth.py	2007-10-10 18:50:28 UTC (rev 1951)
@@ -33,8 +33,8 @@
     @param pszCNonce: The cnonce
 
     @param preHA1: If available this is a str containing a previously
-       calculated HA1 as a hex string. If this is given then the values for
-       pszUserName, pszRealm, and pszPassword are ignored.
+        calculated HA1 as a hex string. If this is given then the values for
+        pszUserName, pszRealm, and pszPassword are ignored.
     """
 
     if (preHA1 and (pszUserName or pszRealm or pszPassword)):
@@ -115,15 +115,15 @@
 def doAuthDigest(username, password, qop, algorithm):
     failures = 0
     
-    result = opendirectory.queryRecordsWithAttribute(
+    result = opendirectory.queryRecordsWithAttribute_list(
         od,
         dsattributes.kDSNAttrRecordName,
         username,
         dsattributes.eDSExact,
         False,
         dsattributes.kDSStdRecordTypeUsers,
-        [dsattributes.kDS1AttrGeneratedUID])
-    guid = result[0][1][dsattributes.kDS1AttrGeneratedUID]
+        [dsattributes.kDSNAttrMetaNodeLocation])
+    nodename = result[0][1][dsattributes.kDSNAttrMetaNodeLocation]
     
     expected = calcResponse(
                 calcHA1(algorithm, username, realm, password, nonce, cnonce),
@@ -147,10 +147,10 @@
     print "    Challenge: %s" % (challenge,)
     print "    Response:  %s" % (response, )
     
-    for x in xrange(attempts):
+    for _ignore_x in xrange(attempts):
         success = opendirectory.authenticateUserDigest(
             od, 
-            guid,
+            nodename,
             username,
             challenge,
             response,
@@ -165,20 +165,20 @@
 def doAuthBasic(username, password):
     failures = 0
     
-    result = opendirectory.queryRecordsWithAttribute(
+    result = opendirectory.queryRecordsWithAttribute_list(
         od,
         dsattributes.kDSNAttrRecordName,
         username,
         dsattributes.eDSExact,
         False,
         dsattributes.kDSStdRecordTypeUsers,
-        [dsattributes.kDS1AttrGeneratedUID])
-    guid = result[0][1][dsattributes.kDS1AttrGeneratedUID]
+        [dsattributes.kDSNAttrMetaNodeLocation])
+    nodename = result[0][1][dsattributes.kDSNAttrMetaNodeLocation]
     
-    for x in xrange(attempts):
+    for _ignore_x in xrange(attempts):
         success = opendirectory.authenticateUserBasic(
             od, 
-            guid,
+            nodename,
             username,
             password,
         )
@@ -191,6 +191,7 @@
 search = raw_input("DS search path: ")
 user = raw_input("User: ")
 pswd = getpass("Password: ")
+attempts = int(raw_input("Number of attempts: "))
 
 od = opendirectory.odInit(search)
 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20071010/4b12d782/attachment-0001.html


More information about the calendarserver-changes mailing list