[CalendarServer-changes] [12127] twext/trunk/twext/who/opendirectory

source_changes at macosforge.org source_changes at macosforge.org
Wed Mar 12 11:20:47 PDT 2014


Revision: 12127
          http://trac.calendarserver.org//changeset/12127
Author:   sagen at apple.com
Date:     2013-12-18 10:29:24 -0800 (Wed, 18 Dec 2013)
Log Message:
-----------
Add more tests, remove opendirectory wrapper and associated modules

Modified Paths:
--------------
    twext/trunk/twext/who/opendirectory/test/test_service.py

Removed Paths:
-------------
    twext/trunk/twext/who/opendirectory/dsattributes.py
    twext/trunk/twext/who/opendirectory/dsquery.py
    twext/trunk/twext/who/opendirectory/opendirectory.py
    twext/trunk/twext/who/opendirectory/setup_directory.py
    twext/trunk/twext/who/opendirectory/setup_testusers.py
    twext/trunk/twext/who/opendirectory/test/test_opendirectory.py

Deleted: twext/trunk/twext/who/opendirectory/dsattributes.py
===================================================================
--- twext/trunk/twext/who/opendirectory/dsattributes.py	2013-12-18 00:50:59 UTC (rev 12126)
+++ twext/trunk/twext/who/opendirectory/dsattributes.py	2013-12-18 18:29:24 UTC (rev 12127)
@@ -1,1894 +0,0 @@
-##
-# Copyright (c) 2006-2013 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-"""
-Record types and attribute names from Directory Service.
-This comes directly (with C->Python conversion) from <DirectoryServices/DirServicesConst.h>
-"""
-
-# Specific match types
-
-eDSExact             =    0x2001
-eDSStartsWith        =    0x2002
-eDSEndsWith          =    0x2003
-eDSContains          =    0x2004
-
-eDSLessThan          =    0x2005
-eDSGreaterThan       =    0x2006
-eDSLessEqual         =    0x2007
-eDSGreaterEqual      =    0x2008
-
-# Specific Record Type Constants
-
-"""
- DirectoryService Specific Record Type Constants
-"""
- 
-"""
- kDSStdRecordTypeAccessControls
-  Record type that contains directory access control directives.
-"""
-kDSStdRecordTypeAccessControls = "dsRecTypeStandard:AccessControls"
-
-"""
- kDSStdRecordTypeAFPServer
-  Record type of AFP server records.
-"""
-kDSStdRecordTypeAFPServer = "dsRecTypeStandard:AFPServer"
-
-"""
- kDSStdRecordTypeAFPUserAliases
-  Record type of AFP user aliases used exclusively by AFP processes.
-"""
-kDSStdRecordTypeAFPUserAliases = "dsRecTypeStandard:AFPUserAliases"
-
-"""
- kDSStdRecordTypeAliases
-  Used to represent alias records.
-"""
-kDSStdRecordTypeAliases = "dsRecTypeStandard:Aliases"
-
-"""
- kDSStdRecordTypeAugments
-  Used to store augmented record data.
-"""
-kDSStdRecordTypeAugments = "dsRecTypeStandard:Augments"
-
-"""
- kDSStdRecordTypeAutomount
-  Used to store automount record data.
-"""
-kDSStdRecordTypeAutomount = "dsRecTypeStandard:Automount"
-
-"""
- kDSStdRecordTypeAutomountMap
-  Used to store automountMap record data.
-"""
-kDSStdRecordTypeAutomountMap = "dsRecTypeStandard:AutomountMap"
-
-"""
- kDSStdRecordTypeAutoServerSetup
-  Used to discover automated server setup information.
-"""
-kDSStdRecordTypeAutoServerSetup = "dsRecTypeStandard:AutoServerSetup"
-
-"""
- kDSStdRecordTypeBootp
-  Record in the local node for storing bootp info.
-"""
-kDSStdRecordTypeBootp = "dsRecTypeStandard:Bootp"
-
-"""
- kDSStdRecordTypeCertificateAuthority
-  Record type that contains certificate authority information.
-"""
-kDSStdRecordTypeCertificateAuthorities = "dsRecTypeStandard:CertificateAuthorities"
-
-"""
- kDSStdRecordTypeComputerLists
-  Identifies computer list records.
-"""
-kDSStdRecordTypeComputerLists = "dsRecTypeStandard:ComputerLists"
-
-"""
- kDSStdRecordTypeComputerGroups
-  Identifies computer group records.
-"""
-kDSStdRecordTypeComputerGroups = "dsRecTypeStandard:ComputerGroups"
-
-"""
- kDSStdRecordTypeComputers
-  Identifies computer records.
-"""
-kDSStdRecordTypeComputers = "dsRecTypeStandard:Computers"
-
-"""
- kDSStdRecordTypeConfig
-  Identifies config records.
-"""
-kDSStdRecordTypeConfig = "dsRecTypeStandard:Config"
-
-"""
- kDSStdRecordTypeEthernets
-  Record in the local node for storing ethernets.
-"""
-kDSStdRecordTypeEthernets = "dsRecTypeStandard:Ethernets"
-
-"""
- kDSStdRecordTypeFileMakerServers
-  FileMaker servers record type. Describes available FileMaker servers, 
-  used for service discovery.
-"""
-kDSStdRecordTypeFileMakerServers = "dsRecTypeStandard:FileMakerServers"
-
-"""
- kDSStdRecordTypeFTPServer
-  Identifies ftp server records.
-"""
-kDSStdRecordTypeFTPServer = "dsRecTypeStandard:FTPServer"
-
-"""
- kDSStdRecordTypeGroupAliases
-  No longer supported in Mac OS X 10.4 or later.
-"""
-kDSStdRecordTypeGroupAliases = "dsRecTypeStandard:GroupAliases"
-
-"""
- kDSStdRecordTypeGroups
-  Identifies group records.
-"""
-kDSStdRecordTypeGroups = "dsRecTypeStandard:Groups"
-
-"""
- kDSStdRecordTypeHostServices
-  Record in the local node for storing host services.
-"""
-kDSStdRecordTypeHostServices = "dsRecTypeStandard:HostServices"
-
-"""
- kDSStdRecordTypeHosts
-  Identifies host records.
-"""
-kDSStdRecordTypeHosts = "dsRecTypeStandard:Hosts"
-
-"""
- kDSStdRecordTypeLDAPServer
-  Identifies LDAP server records.
-"""
-kDSStdRecordTypeLDAPServer = "dsRecTypeStandard:LDAPServer"
-
-"""
- kDSStdRecordTypeLocations
-  Location record type.
-"""
-kDSStdRecordTypeLocations = "dsRecTypeStandard:Locations"
-
-"""
- kDSStdRecordTypeMachines
-  Identifies machine records.
-"""
-kDSStdRecordTypeMachines = "dsRecTypeStandard:Machines"
-
-"""
- kDSStdRecordTypeMaps
-  Identifies map records.
-"""
-kDSStdRecordTypeMaps = "dsRecTypeStandard:Maps"
-
-"""
- kDSStdRecordTypeMeta
-  Identifies meta records.
-"""
-kDSStdRecordTypeMeta = "dsRecTypeStandard:AppleMetaRecord"
-
-"""
- kDSStdRecordTypeMounts
-  Identifies mount records.
-"""
-kDSStdRecordTypeMounts = "dsRecTypeStandard:Mounts"
-
-"""
- kDSStdRecordTypMounts
-  Supported only for backward compatibility to kDSStdRecordTypeMounts.
-"""
-kDSStdRecordTypMounts = "dsRecTypeStandard:Mounts"
-
-"""
- kDSStdRecordTypeNeighborhoods
-  Neighborhood record type. Describes a list of computers and other
-  neighborhoods, used for network browsing.
-"""
-kDSStdRecordTypeNeighborhoods = "dsRecTypeStandard:Neighborhoods"
-
-"""
- kDSStdRecordTypeNFS
-  Identifies NFS records.
-"""
-kDSStdRecordTypeNFS = "dsRecTypeStandard:NFS"
-
-"""
- kDSStdRecordTypeNetDomains
-  Record in the local node for storing net domains.
-"""
-kDSStdRecordTypeNetDomains = "dsRecTypeStandard:NetDomains"
-
-"""
- kDSStdRecordTypeNetGroups
-  Record in the local node for storing net groups.
-"""
-kDSStdRecordTypeNetGroups = "dsRecTypeStandard:NetGroups"
-
-"""
- kDSStdRecordTypeNetworks
-  Identifies network records.
-"""
-kDSStdRecordTypeNetworks = "dsRecTypeStandard:Networks"
-
-"""
- kDSStdRecordTypePasswordServer
-  Used to discover password servers via Bonjour.
-"""
-kDSStdRecordTypePasswordServer = "dsRecTypeStandard:PasswordServer"
-
-"""
- kDSStdRecordTypePeople
-  Record type that contains "People" records used for contact information.
-"""
-kDSStdRecordTypePeople = "dsRecTypeStandard:People"
-
-"""
- kDSStdRecordTypePlaces
-  Identifies places (rooms) records.
-"""
-kDSStdRecordTypePlaces = "dsRecTypeStandard:Places"
-
-"""
- kDSStdRecordTypePresetComputers
-  The computer record type used for presets in record creation.
-"""
-kDSStdRecordTypePresetComputers = "dsRecTypeStandard:PresetComputers"
-
-"""
- kDSStdRecordTypePresetComputerGroups
-  The computer group record type used for presets in record creation.
-"""
-kDSStdRecordTypePresetComputerGroups = "dsRecTypeStandard:PresetComputerGroups"
-
-"""
- kDSStdRecordTypePresetComputerLists
-  The computer list record type used for presets in record creation.
-"""
-kDSStdRecordTypePresetComputerLists = "dsRecTypeStandard:PresetComputerLists"
-
-"""
- kDSStdRecordTypePresetGroups
-  The group record type used for presets in record creation.
-"""
-kDSStdRecordTypePresetGroups = "dsRecTypeStandard:PresetGroups"
-
-"""
- kDSStdRecordTypePresetUsers
-  The user record type used for presets in record creation.
-"""
-kDSStdRecordTypePresetUsers = "dsRecTypeStandard:PresetUsers"
-
-"""
- kDSStdRecordTypePrintService
-  Identifies print service records.
-"""
-kDSStdRecordTypePrintService = "dsRecTypeStandard:PrintService"
-
-"""
- kDSStdRecordTypePrintServiceUser
-  Record in the local node for storing quota usage for a user.
-"""
-kDSStdRecordTypePrintServiceUser = "dsRecTypeStandard:PrintServiceUser"
-
-"""
- kDSStdRecordTypePrinters
-  Identifies printer records.
-"""
-kDSStdRecordTypePrinters = "dsRecTypeStandard:Printers"
-
-"""
- kDSStdRecordTypeProtocols
-  Identifies protocol records.
-"""
-kDSStdRecordTypeProtocols = "dsRecTypeStandard:Protocols"
-
-"""
- kDSStdRecordTypProtocols
-  Supported only for backward compatibility to kDSStdRecordTypeProtocols.
-"""
-kDSStdRecordTypProtocols = "dsRecTypeStandard:Protocols"
-
-"""
- kDSStdRecordTypeQTSServer
-  Identifies quicktime streaming server records.
-"""
-kDSStdRecordTypeQTSServer = "dsRecTypeStandard:QTSServer"
-
-"""
- kDSStdRecordTypeResources
-  Identifies resources used in group services.
-"""
-kDSStdRecordTypeResources = "dsRecTypeStandard:Resources"
-
-"""
- kDSStdRecordTypeRPC
-  Identifies remote procedure call records.
-"""
-kDSStdRecordTypeRPC = "dsRecTypeStandard:RPC"
-
-"""
- kDSStdRecordTypRPC
-  Supported only for backward compatibility to kDSStdRecordTypeRPC.
-"""
-kDSStdRecordTypRPC = "dsRecTypeStandard:RPC"
-
-"""
- kDSStdRecordTypeSMBServer
-  Identifies SMB server records.
-"""
-kDSStdRecordTypeSMBServer = "dsRecTypeStandard:SMBServer"
-
-"""
- kDSStdRecordTypeServer
-  Identifies generic server records.
-"""
-kDSStdRecordTypeServer = "dsRecTypeStandard:Server"
-
-"""
- kDSStdRecordTypeServices
-  Identifies directory based service records.
-"""
-kDSStdRecordTypeServices = "dsRecTypeStandard:Services"
-
-"""
- kDSStdRecordTypeSharePoints
-  Share point record type.
-"""
-kDSStdRecordTypeSharePoints = "dsRecTypeStandard:SharePoints"
-
-"""
- kDSStdRecordTypeUserAliases
-  No longer supported in Mac OS X 10.4 or later.
-"""
-kDSStdRecordTypeUserAliases = "dsRecTypeStandard:UserAliases"
-
-"""
- kDSStdRecordTypeUsers
-  Identifies user records.
-"""
-kDSStdRecordTypeUsers = "dsRecTypeStandard:Users"
-
-"""
- kDSStdRecordTypeWebServer
-  Identifies web server records.
-"""
-kDSStdRecordTypeWebServer = "dsRecTypeStandard:WebServer"
-
-# Specific Attribute Type Constants
-
-
-"""
- DirectoryService Specific Attribute Type Constants
- As a guideline for the attribute types the following legend is used:
-
-        eDS1xxxxxx  Single Valued Attribute
-
-        eDSNxxxxxx  Multi-Valued Attribute
-
-    NOTE #1: Access controls may prevent any particular client from reading/writting
-            various attribute types.  In addition some attribute types may not be stored at
-            all and could also represent "real-time" data generated by the directory node
-            plug-in.
-
-    NOTE #2: Attributes in the model are available for records and directory nodes.
-"""
- 
-
-# Single Valued Specific Attribute Type Constants
-
-
-"""
- DirectoryService Single Valued Specific Attribute Type Constants
-"""
-
-"""
-    kDS1AttrAdminLimits
-    XML plist indicating what an admin user can edit.
-        Found in kDSStdRecordTypeUsers records.
-"""
-kDS1AttrAdminLimits = "dsAttrTypeStandard:AdminLimits"
-
-"""
- kDS1AttrAliasData
- Used to identify alias data.
-"""
-kDS1AttrAliasData = "dsAttrTypeStandard:AppleAliasData"
-
-"""
- kDS1AttrAlternateDatastoreLocation
- Unix path used for determining where a user's email is stored.
-"""
-kDS1AttrAlternateDatastoreLocation = "dsAttrTypeStandard:AlternateDatastoreLocation"
-
-"""
- kDS1AttrAuthenticationHint
- Used to identify the authentication hint phrase.
-"""
-kDS1AttrAuthenticationHint = "dsAttrTypeStandard:AuthenticationHint"
-
-"""
- kDSNAttrAttributeTypes
- Used to indicated recommended attribute types for a record type in the Config node.
-"""
-kDSNAttrAttributeTypes = "dsAttrTypeStandard:AttributeTypes"
-
-"""
- kDS1AttrAuthorityRevocationList
- Attribute containing the binary of the authority revocation list.
- A certificate revocation list that defines certificate authority certificates
- which are no longer trusted.  No user certificates are included in this list.
- Usually found in kDSStdRecordTypeCertificateAuthority records.
-"""
-kDS1AttrAuthorityRevocationList = "dsAttrTypeStandard:AuthorityRevocationList"
-
-"""
- kDS1AttrBirthday
- Single-valued attribute that defines the user's birthday.
- Format is x.208 standard YYYYMMDDHHMMSSZ which we will require as GMT time.
-"""
-kDS1AttrBirthday = "dsAttrTypeStandard:Birthday"
-
-
-"""
- kDS1AttrBootFile
- Attribute type in host or machine records for the name of the 
-        kernel that this machine will use by default when NetBooting.
-"""
-kDS1AttrBootFile = "dsAttrTypeStandard:BootFile"
-
-"""
- kDS1AttrCACertificate
- Attribute containing the binary of the certificate of a
- certificate authority. Its corresponding private key is used to sign certificates.
- Usually found in kDSStdRecordTypeCertificateAuthority records.
-"""
-kDS1AttrCACertificate = "dsAttrTypeStandard:CACertificate"
-
-"""
- kDS1AttrCapabilities
- Used with directory nodes so that clients can "discover" the
- API capabilities for this Directory Node.
-"""
-kDS1AttrCapabilities = "dsAttrTypeStandard:Capabilities"
-
-"""
- kDS1AttrCapacity
- Attribute type for the capacity of a resource. 
-     found in resource records (kDSStdRecordTypeResources). 
-    Example: 50
-"""
-kDS1AttrCapacity = "dsAttrTypeStandard:Capacity"
-
-"""
-    kDS1AttrCategory
-    The category of an item used for browsing
-"""
-kDS1AttrCategory = "dsAttrTypeStandard:Category"
-
-"""
- kDS1AttrCertificateRevocationList
- Attribute containing the binary of the certificate revocation list.
- This is a list of certificates which are no longer trusted.
- Usually found in kDSStdRecordTypeCertificateAuthority records.
-"""
-kDS1AttrCertificateRevocationList = "dsAttrTypeStandard:CertificateRevocationList"
-
-"""
- kDS1AttrChange
- Retained for backward compatibility.
-"""
-kDS1AttrChange = "dsAttrTypeStandard:Change"
-
-"""
- kDS1AttrComment
- Attribute used for unformatted comment.
-"""
-kDS1AttrComment = "dsAttrTypeStandard:Comment"
-
-"""
- kDS1AttrContactGUID
- Attribute type for the contact GUID of a group. 
-     found in group records (kDSStdRecordTypeGroups). 
-"""
-kDS1AttrContactGUID = "dsAttrTypeStandard:ContactGUID"
-
-"""
- kDS1AttrContactPerson
- Attribute type for the contact person of the machine. 
-        Found in host or machine records.
-"""
-kDS1AttrContactPerson = "dsAttrTypeStandard:ContactPerson"
-
-"""
- kDS1AttrCreationTimestamp
- Attribute showing date/time of record creation.
- Format is x.208 standard YYYYMMDDHHMMSSZ which we will require as GMT time.
-"""
-kDS1AttrCreationTimestamp = "dsAttrTypeStandard:CreationTimestamp"
-
-"""
- kDS1AttrCrossCertificatePair
- Attribute containing the binary of a pair of certificates which 
- verify each other.  Both certificates have the same level of authority.
- Usually found in kDSStdRecordTypeCertificateAuthority records.
-"""
-kDS1AttrCrossCertificatePair = "dsAttrTypeStandard:CrossCertificatePair"
-
-"""
- kDS1AttrDataStamp
- checksum/meta data
-"""
-kDS1AttrDataStamp = "dsAttrTypeStandard:DataStamp"
-
-"""
- kDS1AttrDistinguishedName
- Users distinguished or real name
-"""
-kDS1AttrDistinguishedName = "dsAttrTypeStandard:RealName"
-
-"""
- kDS1AttrDNSDomain
- DNS Resolver domain attribute.
-"""
-kDS1AttrDNSDomain = "dsAttrTypeStandard:DNSDomain"
-
-"""
- kDS1AttrDNSNameServer
- DNS Resolver nameserver attribute.
-"""
-kDS1AttrDNSNameServer = "dsAttrTypeStandard:DNSNameServer"
-
-"""
- kDS1AttrENetAddress
- Single-valued attribute for hardware Ethernet address (MAC address).
-        Found in machine records (kDSStdRecordTypeMachines) and computer records
-        (kDSStdRecordTypeComputers).
-"""
-kDS1AttrENetAddress = "dsAttrTypeStandard:ENetAddress"
-
-"""
- kDS1AttrExpire
- Used for expiration date or time depending on association.
-"""
-kDS1AttrExpire = "dsAttrTypeStandard:Expire"
-
-"""
- kDS1AttrFirstName
- Used for first name of user or person record.
-"""
-kDS1AttrFirstName = "dsAttrTypeStandard:FirstName"
-
-"""
- kDS1AttrGeneratedUID
- Used for 36 character (128 bit) unique ID. Usually found in user, 
- group, and computer records. An example value is "A579E95E-CDFE-4EBC-B7E7-F2158562170F".
- The standard format contains 32 hex characters and four hyphen characters.
-"""
-kDS1AttrGeneratedUID = "dsAttrTypeStandard:GeneratedUID"
-
-"""
-    kDS1AttrHomeDirectoryQuota
-    Represents the allowed usage for a user's home directory in bytes.
-        Found in user records (kDSStdRecordTypeUsers).
-"""
-kDS1AttrHomeDirectoryQuota = "dsAttrTypeStandard:HomeDirectoryQuota"
-
-"""
- kDS1AttrHomeDirectorySoftQuota
- Used to define home directory size limit in bytes when user is notified
- that the hard limit is approaching.
-"""
-kDS1AttrHomeDirectorySoftQuota = "dsAttrTypeStandard:HomeDirectorySoftQuota"
-
-"""
-    kDS1AttrHomeLocOwner
-    Represents the owner of a workgroup's shared home directory.
-        Typically found in kDSStdRecordTypeGroups records.
-"""
-kDS1AttrHomeLocOwner = "dsAttrTypeStandard:HomeLocOwner"
-
-"""
-    kDS1StandardAttrHomeLocOwner
-    Retained for backward compatibility.
-"""
-kDS1StandardAttrHomeLocOwner = kDS1AttrHomeLocOwner
-
-"""
- kDS1AttrInternetAlias
- Used to track internet alias.
-"""
-kDS1AttrInternetAlias = "dsAttrTypeStandard:InetAlias"
-
-"""
- kDS1AttrKDCConfigData
- Contents of the kdc.conf file.
-"""
-kDS1AttrKDCConfigData = "dsAttrTypeStandard:KDCConfigData"
-
-"""
- kDS1AttrLastName
- Used for the last name of user or person record.
-"""
-kDS1AttrLastName = "dsAttrTypeStandard:LastName"
-
-"""
- kDS1AttrLDAPSearchBaseSuffix
- Search base suffix for a LDAP server.
-"""
-kDS1AttrLDAPSearchBaseSuffix = "dsAttrTypeStandard:LDAPSearchBaseSuffix"
-
-"""
- kDS1AttrLocation
- Represents the location a service is available from (usually domain name).
-     Typically found in service record types including kDSStdRecordTypeAFPServer,
-     kDSStdRecordTypeLDAPServer, and kDSStdRecordTypeWebServer.
-"""
-kDS1AttrLocation = "dsAttrTypeStandard:Location"
-
-"""
- kDS1AttrMapGUID
- Represents the GUID for a record's map.
-"""
-kDS1AttrMapGUID = "dsAttrTypeStandard:MapGUID"
-
-"""
- kDS1AttrMCXFlags
- Used by MCX.
-"""
-kDS1AttrMCXFlags = "dsAttrTypeStandard:MCXFlags"
-
-"""
- kDS1AttrMCXSettings
- Used by MCX.
-"""
-kDS1AttrMCXSettings = "dsAttrTypeStandard:MCXSettings"
-
-"""
- kDS1AttrMailAttribute
- Holds the mail account config data.
-"""
-kDS1AttrMailAttribute = "dsAttrTypeStandard:MailAttribute"
-
-"""
- kDS1AttrMetaAutomountMap
- Used to query for kDSStdRecordTypeAutomount entries associated with a specific 
- kDSStdRecordTypeAutomountMap.
-"""
-kDS1AttrMetaAutomountMap = "dsAttrTypeStandard:MetaAutomountMap"
-
-"""
- kDS1AttrMiddleName
- Used for the middle name of user or person record.
-"""
-kDS1AttrMiddleName = "dsAttrTypeStandard:MiddleName"
-
-"""
- kDS1AttrModificationTimestamp
- Attribute showing date/time of record modification.
- Format is x.208 standard YYYYMMDDHHMMSSZ which we will require as GMT time.
-"""
-kDS1AttrModificationTimestamp = "dsAttrTypeStandard:ModificationTimestamp"
-
-"""
- kDSNAttrNeighborhoodAlias
- Attribute type in Neighborhood records describing sub-neighborhood records.
-"""
-kDSNAttrNeighborhoodAlias = "dsAttrTypeStandard:NeighborhoodAlias"
-
-"""
- kDS1AttrNeighborhoodType
- Attribute type in Neighborhood records describing their function.
-"""
-kDS1AttrNeighborhoodType = "dsAttrTypeStandard:NeighborhoodType"
-
-"""
- kDS1AttrNetworkView
- The name of the managed network view a computer should use for browsing.
-"""
-kDS1AttrNetworkView = "dsAttrTypeStandard:NetworkView"
-
-"""
- kDS1AttrNFSHomeDirectory
- Defines a user's home directory mount point on the local machine.
-"""
-kDS1AttrNFSHomeDirectory = "dsAttrTypeStandard:NFSHomeDirectory"
-
-"""
- kDS1AttrNote
- Note attribute. Commonly used in printer records.
-"""
-kDS1AttrNote = "dsAttrTypeStandard:Note"
-
-"""
- kDS1AttrOwner
- Attribute type for the owner of a record. 
-        Typically the value is a LDAP distinguished name.
-"""
-kDS1AttrOwner = "dsAttrTypeStandard:Owner"
-
-"""
- kDS1AttrOwnerGUID
- Attribute type for the owner GUID of a group. 
-     found in group records (kDSStdRecordTypeGroups). 
-"""
-kDS1AttrOwnerGUID = "dsAttrTypeStandard:OwnerGUID"
-
-"""
- kDS1AttrPassword
- Holds the password or credential value.
-"""
-kDS1AttrPassword = "dsAttrTypeStandard:Password"
-
-"""
- kDS1AttrPasswordPlus
- Holds marker data to indicate possible authentication redirection.
-"""
-kDS1AttrPasswordPlus = "dsAttrTypeStandard:PasswordPlus"
-
-"""
- kDS1AttrPasswordPolicyOptions
- Collection of password policy options in single attribute.
- Used in user presets record.
-"""
-kDS1AttrPasswordPolicyOptions = "dsAttrTypeStandard:PasswordPolicyOptions"
-
-"""
- kDS1AttrPasswordServerList
- Represents the attribute for storing the password server's replication information.
-"""
-kDS1AttrPasswordServerList = "dsAttrTypeStandard:PasswordServerList"
-
-"""
-    kDS1AttrPasswordServerLocation
-    Specifies the IP address or domain name of the Password Server associated
-        with a given directory node. Found in a config record named PasswordServer.
-"""
-kDS1AttrPasswordServerLocation = "dsAttrTypeStandard:PasswordServerLocation"
-
-"""
- kDS1AttrPicture
- Represents the path of the picture for each user displayed in the login window.
- Found in user records (kDSStdRecordTypeUsers).
-"""
-kDS1AttrPicture = "dsAttrTypeStandard:Picture"
-
-"""
- kDS1AttrPort
- Represents the port number a service is available on.
-     Typically found in service record types including kDSStdRecordTypeAFPServer,
-     kDSStdRecordTypeLDAPServer, and kDSStdRecordTypeWebServer.
-"""
-kDS1AttrPort = "dsAttrTypeStandard:Port"
-
-"""
-    kDS1AttrPresetUserIsAdmin
-    Flag to indicate whether users created from this preset are administrators
-        by default. Found in kDSStdRecordTypePresetUsers records.
-"""
-kDS1AttrPresetUserIsAdmin = "dsAttrTypeStandard:PresetUserIsAdmin"
-
-"""
- kDS1AttrPrimaryComputerGUID
- Single-valued attribute that defines a primary computer of the computer group.  
- added via extensible object for computer group record type (kDSStdRecordTypeComputerGroups)
-"""
-kDS1AttrPrimaryComputerGUID = "dsAttrTypeStandard:PrimaryComputerGUID"
-
-"""
- kDS1AttrPrimaryComputerList
- The GUID of the computer list with which this computer record is associated.
-"""
-kDS1AttrPrimaryComputerList = "dsAttrTypeStandard:PrimaryComputerList"
-
-"""
- kDS1AttrPrimaryGroupID
- This is the 32 bit unique ID that represents the primary group 
- a user is part of, or the ID of a group. Format is a signed 32 bit integer
- represented as a string.
-"""
-kDS1AttrPrimaryGroupID = "dsAttrTypeStandard:PrimaryGroupID"
-
-"""
- kDS1AttrPrinter1284DeviceID
- Single-valued attribute that defines the IEEE 1284 DeviceID of a printer.
-              This is used when configuring a printer.
-"""
-kDS1AttrPrinter1284DeviceID = "dsAttrTypeStandard:Printer1284DeviceID"
-
-"""
- kDS1AttrPrinterLPRHost
- Standard attribute type for kDSStdRecordTypePrinters.
-"""
-kDS1AttrPrinterLPRHost = "dsAttrTypeStandard:PrinterLPRHost"
-
-"""
- kDS1AttrPrinterLPRQueue
- Standard attribute type for kDSStdRecordTypePrinters.
-"""
-kDS1AttrPrinterLPRQueue = "dsAttrTypeStandard:PrinterLPRQueue"
-
-"""
- kDS1AttrPrinterMakeAndModel
- Single-valued attribute for definition of the Printer Make and Model.  An example
-              Value would be "HP LaserJet 2200".  This would be used to determine the proper PPD
-              file to be used when configuring a printer from the Directory.  This attribute
-              is based on the IPP Printing Specification RFC and IETF IPP-LDAP Printer Record.
-"""
-kDS1AttrPrinterMakeAndModel = "dsAttrTypeStandard:PrinterMakeAndModel"
-
-"""
- kDS1AttrPrinterType
- Standard attribute type for kDSStdRecordTypePrinters.
-"""
-kDS1AttrPrinterType = "dsAttrTypeStandard:PrinterType"
-
-"""
- kDS1AttrPrinterURI
- Single-valued attribute that defines the URI of a printer "ipp://address" or
-              "smb://server/queue".  This is used when configuring a printer. This attribute
-                is based on the IPP Printing Specification RFC and IETF IPP-LDAP Printer Record.
-"""
-kDS1AttrPrinterURI = "dsAttrTypeStandard:PrinterURI"
-
-"""
- kDS1AttrPrinterXRISupported
- Multi-valued attribute that defines additional URIs supported by a printer.
-              This is used when configuring a printer. This attribute is based on the IPP 
-                Printing Specification RFC and IETF IPP-LDAP Printer Record.
-"""
-kDSNAttrPrinterXRISupported = "dsAttrTypeStandard:PrinterXRISupported"
-
-"""
- kDS1AttrPrintServiceInfoText
- Standard attribute type for kDSStdRecordTypePrinters.
-"""
-kDS1AttrPrintServiceInfoText = "dsAttrTypeStandard:PrintServiceInfoText"
-
-"""
- kDS1AttrPrintServiceInfoXML
- Standard attribute type for kDSStdRecordTypePrinters.
-"""
-kDS1AttrPrintServiceInfoXML = "dsAttrTypeStandard:PrintServiceInfoXML"
-
-"""
- kDS1AttrPrintServiceUserData
- Single-valued attribute for print quota configuration or statistics
-        (XML data). Found in user records (kDSStdRecordTypeUsers) or print service
-        statistics records (kDSStdRecordTypePrintServiceUser).
-"""
-kDS1AttrPrintServiceUserData = "dsAttrTypeStandard:PrintServiceUserData"
-
-"""
- kDS1AttrRealUserID
- Used by MCX.
-"""
-kDS1AttrRealUserID = "dsAttrTypeStandard:RealUserID"
-
-"""
- kDS1AttrRelativeDNPrefix
- Used to map the first native LDAP attribute type required in the building of the
-  Relative Distinguished Name for LDAP record creation.
-"""
-kDS1AttrRelativeDNPrefix = "dsAttrTypeStandard:RelativeDNPrefix"
-
-"""
- kDS1AttrSMBAcctFlags
- Account control flag.
-"""
-kDS1AttrSMBAcctFlags = "dsAttrTypeStandard:SMBAccountFlags"
-
-"""
- kDS1AttrSMBGroupRID
- Constant for supporting PDC SMB interaction with DS.
-"""
-kDS1AttrSMBGroupRID = "dsAttrTypeStandard:SMBGroupRID"
-
-"""
- kDS1AttrSMBHome
- 
-     UNC address of Windows homedirectory mount point (\\server\\sharepoint).
-"""
-kDS1AttrSMBHome = "dsAttrTypeStandard:SMBHome"
-
-"""
- kDS1AttrSMBHomeDrive
- 
-     Drive letter for homedirectory mount point.
-"""
-kDS1AttrSMBHomeDrive = "dsAttrTypeStandard:SMBHomeDrive"
-
-"""
- kDS1AttrSMBKickoffTime
- Attribute in support of SMB interaction.
-"""
-kDS1AttrSMBKickoffTime = "dsAttrTypeStandard:SMBKickoffTime"
-
-"""
- kDS1AttrSMBLogoffTime
- Attribute in support of SMB interaction.
-"""
-kDS1AttrSMBLogoffTime = "dsAttrTypeStandard:SMBLogoffTime"
-
-"""
- kDS1AttrSMBLogonTime
- Attribute in support of SMB interaction.
-"""
-kDS1AttrSMBLogonTime = "dsAttrTypeStandard:SMBLogonTime"
-
-"""
- kDS1AttrSMBPrimaryGroupSID
- SMB Primary Group Security ID, stored as a string attribute of
-    up to 64 bytes. Found in user, group, and computer records
-    (kDSStdRecordTypeUsers, kDSStdRecordTypeGroups, kDSStdRecordTypeComputers).
-"""
-kDS1AttrSMBPrimaryGroupSID = "dsAttrTypeStandard:SMBPrimaryGroupSID"
-
-"""
- kDS1AttrSMBPWDLastSet
- Attribute in support of SMB interaction.
-"""
-kDS1AttrSMBPWDLastSet = "dsAttrTypeStandard:SMBPasswordLastSet"
-
-"""
- kDS1AttrSMBProfilePath
- Desktop management info (dock, desktop links, etc).
-"""
-kDS1AttrSMBProfilePath = "dsAttrTypeStandard:SMBProfilePath"
-
-"""
- kDS1AttrSMBRID
- Attribute in support of SMB interaction.
-"""
-kDS1AttrSMBRID = "dsAttrTypeStandard:SMBRID"
-
-"""
- kDS1AttrSMBScriptPath
- Login script path.
-"""
-kDS1AttrSMBScriptPath = "dsAttrTypeStandard:SMBScriptPath"
-
-"""
- kDS1AttrSMBSID
- SMB Security ID, stored as a string attribute of up to 64 bytes.
-    Found in user, group, and computer records (kDSStdRecordTypeUsers, 
-    kDSStdRecordTypeGroups, kDSStdRecordTypeComputers).
-"""
-kDS1AttrSMBSID = "dsAttrTypeStandard:SMBSID"
-
-"""
- kDS1AttrSMBUserWorkstations
- List of workstations user can login from (machine account names).
-"""
-kDS1AttrSMBUserWorkstations = "dsAttrTypeStandard:SMBUserWorkstations"
-
-"""
- kDS1AttrServiceType
- Represents the service type for the service.  This is the raw service type of the
-     service.  For example a service record type of kDSStdRecordTypeWebServer 
-     might have a service type of "http" or "https".
-"""
-kDS1AttrServiceType = "dsAttrTypeStandard:ServiceType"
-
-"""
- kDS1AttrSetupAdvertising
- Used for Setup Assistant automatic population.
-"""
-kDS1AttrSetupAdvertising = "dsAttrTypeStandard:SetupAssistantAdvertising"
-
-"""
- kDS1AttrSetupAutoRegister
- Used for Setup Assistant automatic population.
-"""
-kDS1AttrSetupAutoRegister = "dsAttrTypeStandard:SetupAssistantAutoRegister"
-
-"""
- kDS1AttrSetupLocation
- Used for Setup Assistant automatic population.
-"""
-kDS1AttrSetupLocation = "dsAttrTypeStandard:SetupAssistantLocation"
-
-"""
- kDS1AttrSetupOccupation
- Used for Setup Assistant automatic population.
-"""
-kDS1AttrSetupOccupation = "dsAttrTypeStandard:Occupation"
-
-"""
- kDS1AttrTimeToLive
- Attribute recommending how long to cache the record's attribute values.
- Format is an unsigned 32 bit representing seconds. ie. 300 is 5 minutes.
-"""
-kDS1AttrTimeToLive = "dsAttrTypeStandard:TimeToLive"
-
-"""
- kDS1AttrUniqueID
- This is the 32 bit unique ID that represents the user in the legacy manner.
- Format is a signed integer represented as a string.
-"""
-kDS1AttrUniqueID = "dsAttrTypeStandard:UniqueID"
-
-"""
- kDS1AttrUserCertificate
- Attribute containing the binary of the user's certificate.
- Usually found in user records. The certificate is data which identifies a user.
- This data is attested to by a known party, and can be independently verified 
- by a third party.
-"""
-kDS1AttrUserCertificate = "dsAttrTypeStandard:UserCertificate"
-
-"""
- kDS1AttrUserPKCS12Data
- Attribute containing binary data in PKCS #12 format. 
- Usually found in user records. The value can contain keys, certificates,
- and other related information and is encrypted with a passphrase.
-"""
-kDS1AttrUserPKCS12Data = "dsAttrTypeStandard:UserPKCS12Data"
-
-"""
- kDS1AttrUserShell
- Used to represent the user's shell setting.
-"""
-kDS1AttrUserShell = "dsAttrTypeStandard:UserShell"
-
-"""
- kDS1AttrUserSMIMECertificate
- Attribute containing the binary of the user's SMIME certificate.
- Usually found in user records. The certificate is data which identifies a user.
- This data is attested to by a known party, and can be independently verified 
- by a third party. SMIME certificates are often used for signed or encrypted
- emails.
-"""
-kDS1AttrUserSMIMECertificate = "dsAttrTypeStandard:UserSMIMECertificate"
-
-"""
- kDS1AttrVFSDumpFreq
- Attribute used to support mount records.
-"""
-kDS1AttrVFSDumpFreq = "dsAttrTypeStandard:VFSDumpFreq"
-
-"""
- kDS1AttrVFSLinkDir
- Attribute used to support mount records.
-"""
-kDS1AttrVFSLinkDir = "dsAttrTypeStandard:VFSLinkDir"
-
-"""
- kDS1AttrVFSPassNo
- Attribute used to support mount records.
-"""
-kDS1AttrVFSPassNo = "dsAttrTypeStandard:VFSPassNo"
-
-"""
- kDS1AttrVFSType
- Attribute used to support mount records.
-"""
-kDS1AttrVFSType = "dsAttrTypeStandard:VFSType"
-
-"""
- kDS1AttrWeblogURI
- Single-valued attribute that defines the URI of a user's weblog.
-    Usually found in user records (kDSStdRecordTypeUsers). 
-    Example: http://example.com/blog/jsmith
-"""
-kDS1AttrWeblogURI = "dsAttrTypeStandard:WeblogURI"
-
-"""
-    kDS1AttrXMLPlist
-    SA config settings plist.
-"""
-kDS1AttrXMLPlist = "dsAttrTypeStandard:XMLPlist"
-
-"""
- kDS1AttrProtocolNumber
- Single-valued attribute that defines a protocol number.  Usually found
-  in protocol records (kDSStdRecordTypeProtocols)
-"""
-kDS1AttrProtocolNumber = "dsAttrTypeStandard:ProtocolNumber"
-
-"""
- kDS1AttrRPCNumber
- Single-valued attribute that defines an RPC number.  Usually found
-  in RPC records (kDSStdRecordTypeRPC)
-"""
-kDS1AttrRPCNumber = "dsAttrTypeStandard:RPCNumber"
-
-"""
- kDS1AttrNetworkNumber
- Single-valued attribute that defines a network number.  Usually found
-  in network records (kDSStdRecordTypeNetworks)
-"""
-kDS1AttrNetworkNumber = "dsAttrTypeStandard:NetworkNumber"
-
-
-# Multiple Valued Specific Attribute Type Constants
-
-
-"""
- DirectoryService Multiple Valued Specific Attribute Type Constants
-"""
-
-"""
- kDSNAttrAccessControlEntry
- Attribute type which stores directory access control directives.
-"""
-kDSNAttrAccessControlEntry = "dsAttrTypeStandard:AccessControlEntry"
-
-"""
- kDSNAttrAddressLine1
- Line one of multiple lines of address data for a user.
-"""
-kDSNAttrAddressLine1 = "dsAttrTypeStandard:AddressLine1"
-
-"""
- kDSNAttrAddressLine2
- Line two of multiple lines of address data for a user.
-"""
-kDSNAttrAddressLine2 = "dsAttrTypeStandard:AddressLine2"
-
-"""
- kDSNAttrAddressLine3
- Line three of multiple lines of address data for a user.
-"""
-kDSNAttrAddressLine3 = "dsAttrTypeStandard:AddressLine3"
-
-"""
- kDSNAttrAltSecurityIdentities
- Alternative Security Identities such as Kerberos principals.
-"""
-kDSNAttrAltSecurityIdentities = "dsAttrTypeStandard:AltSecurityIdentities"
-
-"""
- kDSNAttrAreaCode
- Area code of a user's phone number.
-"""
-kDSNAttrAreaCode = "dsAttrTypeStandard:AreaCode"
-
-"""
- kDSNAttrAuthenticationAuthority
- Determines what mechanism is used to verify or set a user's password.
-     If multiple values are present, the first attributes returned take precedence.
-     Typically found in User records (kDSStdRecordTypeUsers).
-"""
-kDSNAttrAuthenticationAuthority = "dsAttrTypeStandard:AuthenticationAuthority"
-
-"""
- kDSNAttrAutomountInformation
- Used to store automount information in kDSStdRecordTypeAutomount records.
-"""
-kDSNAttrAutomountInformation = "dsAttrTypeStandard:AutomountInformation"
-
-"""
- kDSNAttrBootParams
- Attribute type in host or machine records for storing boot params.
-"""
-kDSNAttrBootParams = "dsAttrTypeStandard:BootParams"
-
-"""
- kDSNAttrBuilding
- Represents the building name for a user or person record.
- Usually found in user or people records (kDSStdRecordTypeUsers or 
- kDSStdRecordTypePeople).
-"""
-kDSNAttrBuilding = "dsAttrTypeStandard:Building"
-
-"""
- kDSNAttrCalendarPrincipalURI
- the URI for a record's calendar
-"""
-kDSNAttrCalendarPrincipalURI = "dsAttrTypeStandard:CalendarPrincipalURI"
-
-"""
- kDSNAttrCity
- Usually, city for a user or person record.
- Usually found in user or people records (kDSStdRecordTypeUsers or 
- kDSStdRecordTypePeople).
-"""
-kDSNAttrCity = "dsAttrTypeStandard:City"
-
-"""
- kDSNAttrCompany
- attribute that defines the user's company.
- Example: Apple Computer, Inc
-"""
-kDSNAttrCompany = "dsAttrTypeStandard:Company"
-
-"""
- kDSNAttrComputerAlias
- Attribute type in Neighborhood records describing computer records pointed to by
- this neighborhood.
-"""
-kDSNAttrComputerAlias = "dsAttrTypeStandard:ComputerAlias"
-
-"""
- kDSNAttrComputers
- List of computers.
-"""
-kDSNAttrComputers = "dsAttrTypeStandard:Computers"
-
-"""
- kDSNAttrCountry
- Represents country of a record entry.
- Usually found in user or people records (kDSStdRecordTypeUsers or 
- kDSStdRecordTypePeople).
-"""
-kDSNAttrCountry = "dsAttrTypeStandard:Country"
-
-"""
- kDSNAttrDepartment
- Represents the department name of a user or person.
- Usually found in user or people records (kDSStdRecordTypeUsers or 
- kDSStdRecordTypePeople).
-"""
-kDSNAttrDepartment = "dsAttrTypeStandard:Department"
-
-"""
- kDSNAttrDNSName
- Domain Name Service name.
-"""
-kDSNAttrDNSName = "dsAttrTypeStandard:DNSName"
-
-"""
- kDSNAttrEMailAddress
- Email address of usually a user record.
-"""
-kDSNAttrEMailAddress = "dsAttrTypeStandard:EMailAddress"
-
-"""
- kDSNAttrEMailContacts
- multi-valued attribute that defines a record's custom email addresses .
-     found in user records (kDSStdRecordTypeUsers). 
-    Example: home:johndoe at mymail.com
-"""
-kDSNAttrEMailContacts = "dsAttrTypeStandard:EMailContacts"
-
-"""
- kDSNAttrFaxNumber
- Represents the FAX numbers of a user or person.
- Usually found in user or people records (kDSStdRecordTypeUsers or 
- kDSStdRecordTypePeople).
-"""
-kDSNAttrFaxNumber = "dsAttrTypeStandard:FAXNumber"
-
-"""
- kDSNAttrGroup
- List of groups.
-"""
-kDSNAttrGroup = "dsAttrTypeStandard:Group"
-
-"""
- kDSNAttrGroupMembers
- Attribute type in group records containing lists of GUID values for members other than groups.
-"""
-kDSNAttrGroupMembers = "dsAttrTypeStandard:GroupMembers"
-
-"""
- kDSNAttrGroupMembership
- Usually a list of users that below to a given group record.
-"""
-kDSNAttrGroupMembership = "dsAttrTypeStandard:GroupMembership"
-
-"""
- kDSNAttrGroupServices
- xml-plist attribute that defines a group's services .
-     found in group records (kDSStdRecordTypeGroups). 
-"""
-kDSNAttrGroupServices = "dsAttrTypeStandard:GroupServices"
-
-"""
- kDSNAttrHomePhoneNumber
- Home telephone number of a user or person.
-"""
-kDSNAttrHomePhoneNumber = "dsAttrTypeStandard:HomePhoneNumber"
-
-"""
- kDSNAttrHTML
- HTML location.
-"""
-kDSNAttrHTML = "dsAttrTypeStandard:HTML"
-
-"""
- kDSNAttrHomeDirectory
- Network home directory URL.
-"""
-kDSNAttrHomeDirectory = "dsAttrTypeStandard:HomeDirectory"
-
-"""
- kDSNAttrIMHandle
- Represents the Instant Messaging handles of a user.
- Values should be prefixed with the appropriate IM type
- ie. AIM:, Jabber:, MSN:, Yahoo:, or ICQ:
- Usually found in user records (kDSStdRecordTypeUsers).
-"""
-kDSNAttrIMHandle = "dsAttrTypeStandard:IMHandle"
-
-"""
- kDSNAttrIPAddress
- IP address expressed either as domain or IP notation.
-"""
-kDSNAttrIPAddress = "dsAttrTypeStandard:IPAddress"
-
-"""
-    kDSNAttrIPAddressAndENetAddress
- A pairing of IPv4 or IPv6 addresses with Ethernet addresses 
- (e.g., "10.1.1.1/00:16:cb:92:56:41").  Usually found on kDSStdRecordTypeComputers for use by 
- services that need specific pairing of the two values.  This should be in addition to 
- kDSNAttrIPAddress, kDSNAttrIPv6Address and kDS1AttrENetAddress. This is necessary because not
- all directories return attribute values in a guaranteed order.
-"""
-kDSNAttrIPAddressAndENetAddress = "dsAttrTypeStandard:IPAddressAndENetAddress"
-
-"""
- kDSNAttrIPv6Address
- IPv6 address expressed in the standard notation (e.g., "fe80::236:caff:fcc2:5641" )
- Usually found on kDSStdRecordTypeComputers, kDSStdRecordTypeHosts, and 
- kDSStdRecordTypeMachines.
-"""
-kDSNAttrIPv6Address = "dsAttrTypeStandard:IPv6Address"
-
-"""
- kDSNAttrJPEGPhoto
- Used to store binary picture data in JPEG format. 
- Usually found in user, people or group records (kDSStdRecordTypeUsers, 
- kDSStdRecordTypePeople, kDSStdRecordTypeGroups).
-"""
-kDSNAttrJPEGPhoto = "dsAttrTypeStandard:JPEGPhoto"
-
-"""
- kDSNAttrJobTitle
- Represents the job title of a user.
- Usually found in user or people records (kDSStdRecordTypeUsers or 
- kDSStdRecordTypePeople).
-"""
-kDSNAttrJobTitle = "dsAttrTypeStandard:JobTitle"
-
-"""
- kDSNAttrKDCAuthKey
- KDC master key RSA encrypted with realm public key.
-"""
-kDSNAttrKDCAuthKey = "dsAttrTypeStandard:KDCAuthKey"
-
-"""
-    kDSNAttrKeywords
-    Keywords using for searching capability.
-"""
-kDSNAttrKeywords = "dsAttrTypeStandard:Keywords"
-
-"""
- kDSNAttrLDAPReadReplicas
- List of LDAP server URLs which can each be used to read directory data.
-"""
-kDSNAttrLDAPReadReplicas = "dsAttrTypeStandard:LDAPReadReplicas"
-
-"""
- kDSNAttrLDAPWriteReplicas
- List of LDAP server URLs which can each be used to write directory data.
-"""
-kDSNAttrLDAPWriteReplicas = "dsAttrTypeStandard:LDAPWriteReplicas"
-
-"""
- kDSNAttrMachineServes
- Attribute type in host or machine records for storing NetInfo 
-        domains served.
-"""
-kDSNAttrMachineServes = "dsAttrTypeStandard:MachineServes"
-
-"""
- kDSNAttrMapCoordinates
- attribute that defines coordinates for a user's location .
-*     found in user records (kDSStdRecordTypeUsers) and resource records (kDSStdRecordTypeResources).
-    Example: 7.7,10.6
-"""
-kDSNAttrMapCoordinates = "dsAttrTypeStandard:MapCoordinates"
-
-"""
- kDSNAttrMapURI
- attribute that defines the URI of a user's location.
-    Usually found in user records (kDSStdRecordTypeUsers). 
-    Example: http://example.com/bldg1
-"""
-kDSNAttrMapURI = "dsAttrTypeStandard:MapURI"
-
-"""
- kDSNAttrMCXSettings
- Used by MCX.
-"""
-kDSNAttrMCXSettings = "dsAttrTypeStandard:MCXSettings"
-
-"""
- kDSNAttrMIME
- Data contained in this attribute type is a fully qualified MIME Type. 
-"""
-kDSNAttrMIME = "dsAttrTypeStandard:MIME"
-
-"""
- kDSNAttrMember
- List of member records. 
-"""
-kDSNAttrMember = "dsAttrTypeStandard:Member"
-
-"""
- kDSNAttrMobileNumber
- Represents the mobile numbers of a user or person.
- Usually found in user or people records (kDSStdRecordTypeUsers or 
- kDSStdRecordTypePeople).
-"""
-kDSNAttrMobileNumber = "dsAttrTypeStandard:MobileNumber"
-
-"""
- kDSNAttrNBPEntry
- Appletalk data.
-"""
-kDSNAttrNBPEntry = "dsAttrTypeStandard:NBPEntry"
-
-"""
- kDSNAttrNestedGroups
- Attribute type in group records for the list of GUID values for nested groups.
-"""
-kDSNAttrNestedGroups = "dsAttrTypeStandard:NestedGroups"
-
-"""
- kDSNAttrNetGroups
- Attribute type that indicates which netgroups its record is a member of.
-        Found in user, host, and netdomain records.
-"""
-kDSNAttrNetGroups = "dsAttrTypeStandard:NetGroups"
-
-"""
- kDSNAttrNickName
- Represents the nickname of a user or person.
- Usually found in user or people records (kDSStdRecordTypeUsers or 
- kDSStdRecordTypePeople).
-"""
-kDSNAttrNickName = "dsAttrTypeStandard:NickName"
-
-"""
- kDSNAttrNodePathXMLPlist
- Attribute type in Neighborhood records describing the DS Node to search while
- looking up aliases in this neighborhood.
-"""
-kDSNAttrNodePathXMLPlist = "dsAttrTypeStandard:NodePathXMLPlist"
-
-"""
- kDSNAttrOrganizationInfo
- Usually the organization info of a user.
-"""
-kDSNAttrOrganizationInfo = "dsAttrTypeStandard:OrganizationInfo"
-
-"""
- kDSNAttrOrganizationName
- Usually the organization of a user.
-"""
-kDSNAttrOrganizationName = "dsAttrTypeStandard:OrganizationName"
-
-"""
- kDSNAttrPagerNumber
- Represents the pager numbers of a user or person.
- Usually found in user or people records (kDSStdRecordTypeUsers or 
- kDSStdRecordTypePeople).
-"""
-kDSNAttrPagerNumber = "dsAttrTypeStandard:PagerNumber"
-
-"""
- kDSNAttrPhoneContacts
- multi-valued attribute that defines a record's custom phone numbers .
-     found in user records (kDSStdRecordTypeUsers). 
-    Example: home fax:408-555-4444
-"""
-kDSNAttrPhoneContacts = "dsAttrTypeStandard:PhoneContacts"
-
-
-"""
- kDSNAttrPhoneNumber
- Telephone number of a user.
-"""
-kDSNAttrPhoneNumber = "dsAttrTypeStandard:PhoneNumber"
-
-"""
- kDSNAttrPGPPublicKey
- Pretty Good Privacy public encryption key.
-"""
-kDSNAttrPGPPublicKey = "dsAttrTypeStandard:PGPPublicKey"
-
-"""
- kDSNAttrPostalAddress
- The postal address usually excluding postal code.
-"""
-kDSNAttrPostalAddress = "dsAttrTypeStandard:PostalAddress"
-
-"""
-* kDSNAttrPostalAddressContacts
-* multi-valued attribute that defines a record's alternate postal addresses .
-*     found in user records (kDSStdRecordTypeUsers) and resource records (kDSStdRecordTypeResources).
-"""
-kDSNAttrPostalAddressContacts = "dsAttrTypeStandard:PostalAddressContacts"
-
-"""
- kDSNAttrPostalCode
- The postal code such as zip code in the USA.
-"""
-kDSNAttrPostalCode = "dsAttrTypeStandard:PostalCode"
-
-"""
- kDSNAttrNamePrefix
- Represents the title prefix of a user or person.
- ie. Mr., Ms., Mrs., Dr., etc.
- Usually found in user or people records (kDSStdRecordTypeUsers or 
- kDSStdRecordTypePeople).
-"""
-kDSNAttrNamePrefix = "dsAttrTypeStandard:NamePrefix"
-
-"""
- kDSNAttrProtocols
- List of protocols.
-"""
-kDSNAttrProtocols = "dsAttrTypeStandard:Protocols"
-
-"""
- kDSNAttrRecordName
- List of names/keys for this record.
-"""
-kDSNAttrRecordName = "dsAttrTypeStandard:RecordName"
-
-"""
- kDSNAttrRelationships
- multi-valued attribute that defines the relationship to the record type .
-     found in user records (kDSStdRecordTypeUsers). 
-    Example: brother:John
-"""
-kDSNAttrRelationships = "dsAttrTypeStandard:Relationships"
-
-"""
-* kDSNAttrResourceInfo
-* multi-valued attribute that defines a resource record's info.
-"""
-kDSNAttrResourceInfo = "dsAttrTypeStandard:ResourceInfo"
-
-"""
- kDSNAttrResourceType
- Attribute type for the kind of resource. 
-     found in resource records (kDSStdRecordTypeResources). 
-    Example: ConferenceRoom
-"""
-kDSNAttrResourceType = "dsAttrTypeStandard:ResourceType"
-
-"""
- kDSNAttrServicesLocator
- Attribute describing the services hosted for the record.
-"""
-kDSNAttrServicesLocator = "dsAttrTypeStandard:ServicesLocator"
-
-"""
- kDSNAttrState
- The state or province of a country.
-"""
-kDSNAttrState = "dsAttrTypeStandard:State"
-
-"""
- kDSNAttrStreet
- Represents the street address of a user or person.
- Usually found in user or people records (kDSStdRecordTypeUsers or 
- kDSStdRecordTypePeople).
-"""
-kDSNAttrStreet = "dsAttrTypeStandard:Street"
-
-"""
- kDSNAttrNameSuffix
- Represents the name suffix of a user or person.
- ie. Jr., Sr., etc.
- Usually found in user or people records (kDSStdRecordTypeUsers or 
- kDSStdRecordTypePeople).
-"""
-kDSNAttrNameSuffix = "dsAttrTypeStandard:NameSuffix"
-
-"""
- kDSNAttrURL
- List of URLs.
-"""
-kDSNAttrURL = "dsAttrTypeStandard:URL"
-
-"""
- kDSNAttrURLForNSL
- List of URLs used by NSL.
-"""
-kDSNAttrURLForNSL = "dsAttrTypeStandard:URLForNSL"
-
-"""
- kDSNAttrVFSOpts
- Used in support of mount records.
-"""
-kDSNAttrVFSOpts = "dsAttrTypeStandard:VFSOpts"
-
-
-
-# Other Attribute Type Constants
-
-
-"""
- DirectoryService Other Attribute Type Constants Not Mapped by Directory Node Plugins
- Mainly used internally by the DirectoryService Daemon or made available via dsGetDirNodeInfo()
-"""
-
-"""
- kDS1AttrAdminStatus
- Retained only for backward compatibility.
-"""
-kDS1AttrAdminStatus = "dsAttrTypeStandard:AdminStatus"
-
-"""
- kDS1AttrAlias
- Alias attribute, contain pointer to another node/record/attribute.
-"""
-kDS1AttrAlias = "dsAttrTypeStandard:Alias"
-
-"""
- kDS1AttrAuthCredential
- An "auth" credential, to be used to authenticate to other Directory nodes.
-"""
-kDS1AttrAuthCredential = "dsAttrTypeStandard:AuthCredential"
-
-"""
- kDS1AttrCopyTimestamp
- Timestamp used in local account caching.
-"""
-kDS1AttrCopyTimestamp = "dsAttrTypeStandard:CopyTimestamp"
-
-"""
-    kDS1AttrDateRecordCreated
-    Date of record creation.
-"""
-kDS1AttrDateRecordCreated = "dsAttrTypeStandard:DateRecordCreated"
-
-"""
- kDS1AttrKerberosRealm
- Supports Kerberized SMB Server services.
-"""
-kDS1AttrKerberosRealm = "dsAttrTypeStandard:KerberosRealm"
-
-"""
- kDS1AttrNTDomainComputerAccount
- Supports Kerberized SMB Server services.
-"""
-kDS1AttrNTDomainComputerAccount = "dsAttrTypeStandard:NTDomainComputerAccount"
-
-"""
- kDSNAttrOriginalHomeDirectory
- Home directory URL used in local account caching.
-"""
-kDSNAttrOriginalHomeDirectory = "dsAttrTypeStandard:OriginalHomeDirectory"
-
-"""
- kDS1AttrOriginalNFSHomeDirectory
- NFS home directory used in local account caching.
-"""
-kDS1AttrOriginalNFSHomeDirectory = "dsAttrTypeStandard:OriginalNFSHomeDirectory"
-
-"""
- kDS1AttrOriginalNodeName
- Nodename used in local account caching.
-"""
-kDS1AttrOriginalNodeName = "dsAttrTypeStandard:OriginalNodeName"
-
-"""
- kDS1AttrPrimaryNTDomain
- Supports Kerberized SMB Server services.
-"""
-kDS1AttrPrimaryNTDomain = "dsAttrTypeStandard:PrimaryNTDomain"
-
-"""
- kDS1AttrPwdAgingPolicy
- Contains the password aging policy data for an authentication capable record.
-"""
-kDS1AttrPwdAgingPolicy = "dsAttrTypeStandard:PwdAgingPolicy"
-
-"""
- kDS1AttrRARA
- Retained only for backward compatibility.
-"""
-kDS1AttrRARA = "dsAttrTypeStandard:RARA"
-
-"""
- kDS1AttrReadOnlyNode
- Can be found using dsGetDirNodeInfo and will return one of
- ReadOnly, ReadWrite, or WriteOnly strings.
- Note that ReadWrite does not imply fully readable or writable
-"""
-kDS1AttrReadOnlyNode = "dsAttrTypeStandard:ReadOnlyNode"
-
-"""
- kDS1AttrRecordImage
- A binary image of the record and all it's attributes.
- Has never been supported.
-"""
-kDS1AttrRecordImage = "dsAttrTypeStandard:RecordImage"
-
-"""
- kDS1AttrSMBGroupRID
- Attributefor supporting PDC SMB interaction.
-"""
-kDS1AttrSMBGroupRID = "dsAttrTypeStandard:SMBGroupRID"
-
-"""
- kDS1AttrTimePackage
- Data of Create, Modify, Backup time in UTC.
-"""
-kDS1AttrTimePackage = "dsAttrTypeStandard:TimePackage"
-
-"""
- kDS1AttrTotalSize
- checksum/meta data.
-"""
-kDS1AttrTotalSize = "dsAttrTypeStandard:TotalSize"
-
-"""
- kDSNAttrAllNames
- Backward compatibility only - all possible names for a record.
- Has never been supported.
-"""
-kDSNAttrAllNames = "dsAttrTypeStandard:AllNames"
-
-"""
- kDSNAttrAuthMethod
- Authentication method for an authentication capable record.
-"""
-kDSNAttrAuthMethod = "dsAttrTypeStandard:AuthMethod"
-
-"""
- kDSNAttrMetaNodeLocation
- Meta attribute returning registered node name by directory node plugin.
-"""
-kDSNAttrMetaNodeLocation = "dsAttrTypeStandard:AppleMetaNodeLocation"
-
-"""
- kDSNAttrNodePath
- Sub strings of a Directory Service Node given in order.
-"""
-kDSNAttrNodePath = "dsAttrTypeStandard:NodePath"
-
-"""
- kDSNAttrPlugInInfo
- Information (version, signature, about, credits, etc.) about the plug-in
- that is actually servicing a particular directory node.
- Has never been supported.
-"""
-kDSNAttrPlugInInfo = "dsAttrTypeStandard:PlugInInfo"
-
-"""
- kDSNAttrRecordAlias
- No longer supported in Mac OS X 10.4 or later.
-"""
-kDSNAttrRecordAlias = "dsAttrTypeStandard:RecordAlias"
-
-"""
- kDSNAttrRecordType
- Single Valued for a Record, Multi-valued for a Directory Node.
-"""
-kDSNAttrRecordType = "dsAttrTypeStandard:RecordType"
-
-"""
- kDSNAttrSchema
- List of attribute types.
-"""
-kDSNAttrSchema = "dsAttrTypeStandard:Scheama"
-
-"""
- kDSNAttrSetPasswdMethod
- Retained only for backward compatibility.
-"""
-kDSNAttrSetPasswdMethod = "dsAttrTypeStandard:SetPasswdMethod"
-
-"""
- kDSNAttrSubNodes
- Attribute of a node which lists the available subnodes
-        of that node.
-"""
-kDSNAttrSubNodes = "dsAttrTypeStandard:SubNodes"
-
-"""
- kStandardSourceAlias
- No longer supported in Mac OS X 10.4 or later.
-"""
-kStandardSourceAlias = "dsAttrTypeStandard:AppleMetaAliasSource"
-
-"""
- kStandardTargetAlias
- No longer supported in Mac OS X 10.4 or later.
-"""
-kStandardTargetAlias = "dsAttrTypeStandard:AppleMetaAliasTarget"
-
-"""
- kDSNAttrNetGroupTriplet
- Multivalued attribute that defines the host, user and domain triplet combinations
-  to support NetGroups.  Each attribute value is comma separated string to maintain the
-  triplet (e.g., host,user,domain).
-"""
-kDSNAttrNetGroupTriplet = "dsAttrTypeStandard:NetGroupTriplet"
-
-
-# Search Node attribute type Constants
-
-
-"""
- Search Node attribute type Constants
-"""
- 
-"""
- kDS1AttrSearchPath
- Search path used by the search node.
-"""
-kDS1AttrSearchPath = "dsAttrTypeStandard:SearchPath"
-
-"""
- kDSNAttrSearchPath
- Retained only for backward compatibility.
-"""
-kDSNAttrSearchPath = "dsAttrTypeStandard:SearchPath"
-
-"""
- kDS1AttrSearchPolicy
- Search policy for the search node.
-"""
-kDS1AttrSearchPolicy = "dsAttrTypeStandard:SearchPolicy"
-
-"""
- kDS1AttrNSPSearchPath
- Automatic search path defined by the search node.
-"""
-kDS1AttrNSPSearchPath = "dsAttrTypeStandard:NSPSearchPath"
-
-"""
- kDSNAttrNSPSearchPath
- Retained only for backward compatibility.
-"""
-kDSNAttrNSPSearchPath = "dsAttrTypeStandard:NSPSearchPath"
-
-"""
- kDS1AttrLSPSearchPath
- Local only search path defined by the search node.
-"""
-kDS1AttrLSPSearchPath = "dsAttrTypeStandard:LSPSearchPath"
-
-"""
- kDSNAttrLSPSearchPath
- Retained only for backward compatibility.
-"""
-kDSNAttrLSPSearchPath = "dsAttrTypeStandard:LSPSearchPath"
-
-"""
- kDS1AttrCSPSearchPath
- Admin user configured custom search path defined by the search node.
-"""
-kDS1AttrCSPSearchPath = "dsAttrTypeStandard:CSPSearchPath"
-
-"""
- kDSNAttrCSPSearchPath
- Retained only for backward compatibility.
-"""
-kDSNAttrCSPSearchPath = "dsAttrTypeStandard:CSPSearchPath"
-

Deleted: twext/trunk/twext/who/opendirectory/dsquery.py
===================================================================
--- twext/trunk/twext/who/opendirectory/dsquery.py	2013-12-18 00:50:59 UTC (rev 12126)
+++ twext/trunk/twext/who/opendirectory/dsquery.py	2013-12-18 18:29:24 UTC (rev 12127)
@@ -1,137 +0,0 @@
-##
-# Copyright (c) 2006-2013 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-##
-from __future__ import print_function
-
-"""
-Compound query builder. We do this in Python to avoid having to mess
-with pass a complex Python object hierarchy into C. These classes allow us to
-build the query in Python and generate the compound query string that the directory
-service C api requires.
-"""
-
-import dsattributes
-
-
-
-class match(object):
-    """
-    Represents and attribute/value match operation.
-    """
-
-    def __init__(self, attribute, value, matchType):
-        self.attribute = attribute
-        self.value = value
-        self.matchType = matchType
-
-    def generate(self):
-        return {
-            dsattributes.eDSExact :        "(%s=%s)",
-            dsattributes.eDSStartsWith :   "(%s=%s*)",
-            dsattributes.eDSEndsWith :     "(%s=*%s)",
-            dsattributes.eDSContains :     "(%s=*%s*)",
-            dsattributes.eDSLessThan :     "(%s<%s)",
-            dsattributes.eDSGreaterThan :  "(%s>%s)",
-        }.get(self.matchType, "(%s=*%s*)") % (self.attribute, self.value,)
-
-class expression(object):
-    """
-    Represents a query expression that includes a boolean operator, and a list
-    of sub-expressions operated on. The sub-expressions can either be another expression
-    object or a match object.
-    """
-
-    AND = "&"
-    OR  = "|"
-    NOT = "!"
-
-    def __init__(self, operator, subexpressions):
-        assert(operator == expression.AND or operator == expression.OR or operator == expression.NOT)
-        self.operator = operator
-        self.subexpressions = subexpressions
-
-    def generate(self):
-        result = ""
-        if self.operator == expression.NOT:
-            result += "("
-            result += self.operator
-            result += self.subexpressions.generate()
-            result += ")"
-        else:
-            if len(self.subexpressions) > 1:
-                result += "("
-                result += self.operator
-            for sub in self.subexpressions:
-                result += sub.generate()
-            if len(self.subexpressions) > 1:
-                result += ")"
-        return result
-
-
-# Do some tests
-if __name__=='__main__':
-    exprs = (
-        (expression(
-            expression.AND, (
-                expression(expression.OR, (match("ResourceType", "xyz", dsattributes.eDSExact), match("ResourceType", "abc", dsattributes.eDSExact))),
-                match("ServicesLocator", "GUID:VGUID:calendar", dsattributes.eDSStartsWith),
-            )
-        ), "(&(|(ResourceType=xyz)(ResourceType=abc))(ServicesLocator=GUID:VGUID:calendar*))"),
-        (expression(
-            expression.AND, (
-                expression(expression.OR, (match("ResourceType", "xyz", dsattributes.eDSStartsWith), match("ResourceType", "abc", dsattributes.eDSEndsWith))),
-                match("ServicesLocator", "GUID:VGUID:calendar", dsattributes.eDSContains),
-            )
-        ), "(&(|(ResourceType=xyz*)(ResourceType=*abc))(ServicesLocator=*GUID:VGUID:calendar*))"),
-        (expression(
-            expression.AND, (
-                expression(expression.AND, (match("ResourceType", "xyz", dsattributes.eDSLessThan), match("ResourceType", "abc", dsattributes.eDSGreaterThan))),
-                match("ServicesLocator", "GUID:VGUID:calendar", 0xBAD),
-            )
-        ), "(&(&(ResourceType<xyz)(ResourceType>abc))(ServicesLocator=*GUID:VGUID:calendar*))"),
-        (expression(
-            expression.AND, (
-                match("ServicesLocator", "GUID:VGUID:calendar", 0xBAD),
-            )
-        ), "(ServicesLocator=*GUID:VGUID:calendar*)"),
-        (expression(
-            expression.NOT, match(dsattributes.kDSNAttrNickName, "", dsattributes.eDSStartsWith )
-        ), "(!(" + dsattributes.kDSNAttrNickName + "=*))"),
-        (expression(
-            expression.AND, (
-               expression(
-                    expression.NOT, match(dsattributes.kDSNAttrNickName, "Billy", dsattributes.eDSContains )
-               ),
-               expression(
-                    expression.NOT, match(dsattributes.kDSNAttrEMailAddress, "Billy", dsattributes.eDSContains )
-               ),
-            ),
-        ), "(&(!(" + dsattributes.kDSNAttrNickName + "=*Billy*))(!(" + dsattributes.kDSNAttrEMailAddress + "=*Billy*)))"),
-        (expression(
-            expression.NOT, expression(
-                    expression.OR, (
-                        match(dsattributes.kDSNAttrNickName, "", dsattributes.eDSStartsWith ),
-                        match(dsattributes.kDSNAttrEMailAddress, "", dsattributes.eDSStartsWith ),
-                    ),
-            ),
-        ), "(!(|("+dsattributes.kDSNAttrNickName+"=*)("+dsattributes.kDSNAttrEMailAddress+"=*)))"),
-    )
-
-    for expr, result in exprs:
-        gen = expr.generate()
-        if gen != result:
-            print("Generate expression %s != %s" % (gen, result,))
-    print("Done.")

Deleted: twext/trunk/twext/who/opendirectory/opendirectory.py
===================================================================
--- twext/trunk/twext/who/opendirectory/opendirectory.py	2013-12-18 00:50:59 UTC (rev 12126)
+++ twext/trunk/twext/who/opendirectory/opendirectory.py	2013-12-18 18:29:24 UTC (rev 12127)
@@ -1,519 +0,0 @@
-##
-# Copyright (c) 2006-2013 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-"""
-OpenDirectory.framework access via PyObjC
-"""
-
-import odframework
-import objc
-import dsattributes
-import base64
-from twext.python.log import Logger
-import Foundation
-
-
-def autoPooled(f):
-    """
-    A decorator which creates an autorelease pool and deletes it, causing it
-    to drain
-    """
-    def autoPooledFunction(*args, **kwds):
-        pool = Foundation.NSAutoreleasePool.alloc().init()
-        try:
-            return f(*args, **kwds)
-        finally:
-            del pool
-    return autoPooledFunction
-
-
-log = Logger()
-
-NUM_TRIES = 3
-
-RETRY_CODES = (
-    5200, # Server unreachable
-    5201, # Server not found
-    5202, # Server error
-    5203, # Server timeout
-    5204, # Contact master
-    5205, # Server communication error
-)
-INCORRECT_CREDENTIALS = 5000
-
-# Single-value attributes (must be converted from lists):
-SINGLE_VALUE_ATTRIBUTES = [
-    dsattributes.kDS1AttrBirthday,
-    dsattributes.kDS1AttrComment,
-    dsattributes.kDS1AttrCreationTimestamp,
-    dsattributes.kDS1AttrDistinguishedName,
-    dsattributes.kDS1AttrFirstName,
-    dsattributes.kDS1AttrGeneratedUID,
-    dsattributes.kDS1AttrLastName,
-    dsattributes.kDS1AttrMiddleName,
-    dsattributes.kDS1AttrModificationTimestamp,
-    dsattributes.kDS1AttrNote,
-    dsattributes.kDS1AttrSearchPath,
-    dsattributes.kDS1AttrUserCertificate,
-    dsattributes.kDS1AttrUserPKCS12Data,
-    dsattributes.kDS1AttrUserSMIMECertificate,
-    dsattributes.kDS1AttrWeblogURI,
-]
-
-MATCHANY = 1
-DIGEST_MD5 = "dsAuthMethodStandard:dsAuthNodeDIGEST-MD5"
-
-class Directory(object):
-    """ Encapsulates OpenDirectory session and node """
-
-    def __init__(self, session, node, nodeName):
-        self.session = session
-        self.node = node
-        self.nodeName = nodeName
-
-    def __str__(self):
-        return "OpenDirectory node: %s" % (self.nodeName)
-
-
-
-def adjustMatchType(matchType, caseInsensitive):
-    """ Return the case-insensitive equivalent matchType """
-    return (matchType | 0x100) if caseInsensitive else matchType
-
-    # return caseInsensitiveEquivalents[matchType] if caseInsensitive else matchType
-
-
-def recordToResult(record, encodings):
-    """
-    Takes an ODRecord and turns it into a (recordName, attributesDictionary)
-    tuple.  Unicode values are converted to utf-8 encoded strings. (Not sure
-    what to do with non-unicode values)
-
-    encodings is a attribute-name-to-encoding mapping, useful for specifying
-    how to decode values.
-    """
-    details, error = record.recordDetailsForAttributes_error_(None, None)
-    if error:
-        log.error("Error: {err}", err=error)
-        raise ODNSError(error)
-    result = {}
-    for key, value in details.iteritems():
-        encoding = encodings.get(key, None)
-        if key in SINGLE_VALUE_ATTRIBUTES:
-            if encoding:
-                if encoding == "base64":
-                    result[key] = base64.b64encode(value.bytes().tobytes())
-            else:
-                if len(value) == 0:
-                    result[key] = None
-                else:
-                    if isinstance(value[0], objc.pyobjc_unicode):
-                        result[key] = unicode(value[0]).encode("utf-8") # convert from pyobjc
-        else:
-            if encoding:
-                if encoding == "base64":
-                    result[key] = [base64.b64encode(v.bytes().tobytes()) for v in value]
-            else:
-                result[key] = [unicode(v).encode("utf-8") for v in value if isinstance(v, objc.pyobjc_unicode)]
-
-    return (details.get(dsattributes.kDSNAttrRecordName, [None])[0], result)
-
-
-def attributeNamesFromList(attributes):
-    """
-    The attributes list can contain string names or tuples of the form (name,
-    encoding).  Return just the names.
-    """
-
-    if attributes is None:
-        attributes = []
-
-    names = []
-    encodings = {}
-    for attribute in attributes:
-        if isinstance(attribute, tuple):
-            names.append(attribute[0])
-            encodings[attribute[0]] = attribute[1]
-        else:
-            names.append(attribute)
-    return names, encodings
-
-
- at autoPooled
-def odInit(nodeName):
-    """
-    Create an Open Directory object to operate on the specified directory service node name.
-
-    @param nodeName: C{str} containing the node name.
-    @return: C{object} an object to be passed to all subsequent functions on success,
-        C{None} on failure.
-    """
-    session = odframework.ODSession.defaultSession()
-
-    tries = NUM_TRIES
-    while tries:
-        node, error = odframework.ODNode.nodeWithSession_name_error_(session,
-            nodeName, None)
-
-        if not error:
-            return Directory(session, node, nodeName)
-
-        code = error.code()
-        log.debug("Received code {code} from node call: {err}", code=code, err=error)
-
-        if code in RETRY_CODES:
-            tries -= 1
-        else:
-            break
-
-    log.error("Error: {err}", err=error)
-    raise ODNSError(error)
-
-
-
- at autoPooled
-def getNodeAttributes(directory, nodeName, attributes):
-    """
-    Return key attributes for the specified directory node. The attributes
-    can be a C{str} for the attribute name, or a C{tuple} or C{list} where the first C{str}
-    is the attribute name, and the second C{str} is an encoding type, either "str" or "base64".
-
-    @param directory: C{Directory} the object obtained from an odInit call.
-    @param nodeName: C{str} containing the OD nodeName to query.
-    @param attributes: C{list} or C{tuple} containing the attributes to return for each record.
-    @return: C{dict} of attributes found.
-    """
-
-    tries = NUM_TRIES
-    while tries:
-
-        details, error = directory.node.nodeDetailsForKeys_error_(attributes, None)
-        if not error:
-            return details
-
-        code = error.code()
-        log.debug("Received code {code} from node details call: {err}", code=code, err=error)
-
-        if code in RETRY_CODES:
-            tries -= 1
-        else:
-            break
-
-    log.error("Error: {err}", err=error)
-    raise ODNSError(error)
-
-
- at autoPooled
-def listAllRecordsWithAttributes_list(directory, recordType, attributes, count=0):
-    """
-    List records in Open Directory, and return key attributes for each one.
-    The attributes can be a C{str} for the attribute name, or a C{tuple} or C{list} where the first C{str}
-    is the attribute name, and the second C{str} is an encoding type, either "str" or "base64".
-
-    @param directory: C{Directory} the object obtained from an odInit call.
-    @param recordType: C{str}, C{tuple} or C{list} containing the OD record types to lookup.
-    @param attributes: C{list} or C{tuple} containing the attributes to return for each record.
-    @param count: C{int} maximum number of records to return (zero returns all).
-    @return: C{list} containing a C{list} of C{str} (record name) and C{dict} attributes
-        for each record found, or C{None} otherwise.
-    """
-    results = []
-    attributeNames, encodings = attributeNamesFromList(attributes)
-
-    tries = NUM_TRIES
-    while tries:
-        query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
-            directory.node,
-            recordType,
-            None,
-            MATCHANY,
-            None,
-            attributeNames,
-            count,
-            None)
-
-        if not error:
-            records, error = query.resultsAllowingPartial_error_(False, None)
-
-        if not error:
-            for record in records:
-                results.append(recordToResult(record, encodings))
-            return results
-
-        code = error.code()
-        log.debug("Received code {code} from query call: {err}", code=code, err=error)
-
-        if code in RETRY_CODES:
-            tries -= 1
-        else:
-            break
-
-    log.error("Error: {err}", err=error)
-    raise ODNSError(error)
-
-
- at autoPooled
-def queryRecordsWithAttribute_list(directory, attr, value, matchType, casei, recordType, attributes, count=0):
-    """
-    List records in Open Directory matching specified attribute/value, and return key attributes for each one.
-    The attributes can be a C{str} for the attribute name, or a C{tuple} or C{list} where the first C{str}
-    is the attribute name, and the second C{str} is an encoding type, either "str" or "base64".
-
-    @param directory: C{Directory} 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-insensitive match, C{False} otherwise.
-    @param recordType: C{str}, C{tuple} or C{list} containing the OD record types to lookup.
-    @param attributes: C{list} or C{tuple} containing the attributes to return for each record.
-    @param count: C{int} maximum number of records to return (zero returns all).
-    @return: C{list} containing a C{list} of C{str} (record name) and C{dict} attributes
-        for each record found, or C{None} otherwise.
-    """
-    results = []
-    attributeNames, encodings = attributeNamesFromList(attributes)
-
-    tries = NUM_TRIES
-    while tries:
-
-        query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
-            directory.node,
-            recordType,
-            attr,
-            adjustMatchType(matchType, casei),
-            value.decode("utf-8"),
-            attributeNames,
-            count,
-            None)
-
-        if not error:
-            records, error = query.resultsAllowingPartial_error_(False, None)
-
-        if not error:
-            for record in records:
-                results.append(recordToResult(record, encodings))
-            return results
-
-        code = error.code()
-        log.debug("Received code {code} from query call: {err}", code=code, err=error)
-
-        if code in RETRY_CODES:
-            tries -= 1
-        else:
-            break
-
-    log.error("Error: {err}", err=error)
-    raise ODNSError(error)
-
-
- at autoPooled
-def queryRecordsWithAttributes_list(directory, compound, casei, recordType, attributes, count=0):
-    """
-    List records in Open Directory matching specified criteria, and return key attributes for each one.
-    The attributes can be a C{str} for the attribute name, or a C{tuple} or C{list} where the first C{str}
-    is the attribute name, and the second C{str} is an encoding type, either "str" or "base64".
-
-    @param directory: C{Directory} 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-insensitive match, C{False} otherwise.
-    @param recordType: C{str}, C{tuple} or C{list} containing the OD record types to lookup.
-    @param attributes: C{list} or C{tuple} containing the attributes to return for each record.
-    @param count: C{int} maximum number of records to return (zero returns all).
-    @return: C{list} containing a C{list} of C{str} (record name) and C{dict} attributes
-        for each record found, or C{None} otherwise.
-    """
-    results = []
-
-    attributeNames, encodings = attributeNamesFromList(attributes)
-
-    tries = NUM_TRIES
-    while tries:
-
-        query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
-            directory.node,
-            recordType,
-            None,
-            0x210B, # adjustMatchType(matchType, casei),
-            compound.decode("utf-8"),
-            attributeNames,
-            count,
-            None)
-
-        if not error:
-            records, error = query.resultsAllowingPartial_error_(False, None)
-
-        if not error:
-            for record in records:
-                results.append(recordToResult(record, encodings))
-            return results
-
-        code = error.code()
-        log.debug("Received code {code} from query call: {err}", code=code, err=error)
-
-        if code in RETRY_CODES:
-            tries -= 1
-        else:
-            break
-
-    log.error("Error: {err}", err=error)
-    raise ODNSError(error)
-
-
-def getUserRecord(directory, user):
-    """
-    Look up the record for the given user within the directory's node
-
-    @param directory: C{Directory} the object obtained from an odInit call.
-    @param user: C{str} the user identifier/directory record name to fetch.
-    @return: OD record if the user was found, None otherwise.
-    """
-    tries = NUM_TRIES
-    while tries:
-
-        record, error = directory.node.recordWithRecordType_name_attributes_error_(
-            dsattributes.kDSStdRecordTypeUsers,
-            user,
-            None,
-            None
-        )
-        if not error:
-            return record
-
-        code = error.code()
-        log.debug("Received code {code} from recordWithRecordType call: {err}", code=code, err=error)
-
-        if code in RETRY_CODES:
-            tries -= 1
-        else:
-            break
-
-    log.error("Error: {err}", err=error)
-    raise ODNSError(error)
-
-
- at autoPooled
-def authenticateUserBasic(directory, nodeName, user, password):
-    """
-    Authenticate a user with a password to Open Directory.
-
-    @param directory: C{Directory} the object obtained from an odInit call.
-    @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.
-    """
-    record = getUserRecord(directory, user)
-    if record is None:
-        raise ODError("Record not found", 0)
-
-    tries = NUM_TRIES
-    while tries:
-
-        log.debug("Checking basic auth for user '{user}' (tries remaining: {tries})", 
-            user=user, tries=tries)
-
-        result, error = record.verifyPassword_error_(password, None)
-        if not error:
-            log.debug("Basic auth for user '{user}' result: {result}", user=user, result=result)
-            return result
-
-        code = error.code()
-
-        if code == INCORRECT_CREDENTIALS:
-            log.debug("Basic auth for user '{user}' failed due to incorrect credentials", user=user)
-            return False
-
-        log.debug("Basic auth for user '{user}' failed with code {code} ({err})",
-            user=user, code=code, err=error)
-
-        if code in RETRY_CODES:
-            tries -= 1
-        else:
-            break
-
-    log.error("Basic auth error: {err}", err=error)
-    raise ODNSError(error)
-
-
- at autoPooled
-def authenticateUserDigest(directory, nodeName, user, challenge, response, method):
-    """
-    Authenticate using HTTP Digest credentials to Open Directory.
-
-    @param directory: C{Directory} the object obtained from an odInit call.
-    @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.
-    @param method: C{str} the HTTP method being used.
-    @return: C{True} if the user was found, C{False} otherwise.
-    """
-    record = getUserRecord(directory, user)
-    if record is None:
-        raise ODError("Record not found", 0)
-
-    tries = NUM_TRIES
-    while tries:
-
-        log.debug("Checking digest auth for user '{user}' (tries remaining: {tries})",
-            user=user, tries=tries)
-
-        # TODO: what are these other return values?
-        result, mystery1, mystery2, error = record.verifyExtendedWithAuthenticationType_authenticationItems_continueItems_context_error_(
-            DIGEST_MD5,
-            [user, challenge, response, method],
-            None, None, None
-        )
-        if not error:
-            log.debug("Digest auth for user '{user}' result: {result}", user=user, result=result)
-            return result
-
-        code = error.code()
-
-        if code == INCORRECT_CREDENTIALS:
-            log.debug("Digest auth for user '{user}' failed due to incorrect credentials", user=user)
-            return False
-
-        log.debug("Digest auth for user '{user}' failed with code {code} ({err})",
-            user=user, code=code, err=error)
-
-        if code in RETRY_CODES:
-            tries -= 1
-        else:
-            break
-
-    log.error("Digest auth error: {err}", err=error)
-    raise ODNSError(error)
-
-
-class ODError(Exception):
-    """
-    Exceptions from DirectoryServices errors.
-    """
-    def __init__(self, msg, code):
-        self.message = (msg, code)
-
-    def __str__(self):
-        return "<OD Error %s %d>" % (self.message[0], self.message[1])
-
-
-class ODNSError(ODError):
-    """
-    Converts an NSError.
-    """
-    def __init__(self, error):
-        super(ODNSError, self).__init__(error.localizedDescription(),
-            error.code())

Deleted: twext/trunk/twext/who/opendirectory/setup_directory.py
===================================================================
--- twext/trunk/twext/who/opendirectory/setup_directory.py	2013-12-18 00:50:59 UTC (rev 12126)
+++ twext/trunk/twext/who/opendirectory/setup_directory.py	2013-12-18 18:29:24 UTC (rev 12127)
@@ -1,381 +0,0 @@
-##
-# Copyright (c) 2010-2013 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-from __future__ import print_function
-
-import os
-import sys
-import odframework
-import dsattributes
-from getopt import getopt, GetoptError
-
-# TODO: Nested groups
-# TODO: GroupMembership
-
-masterNodeName = "/LDAPv3/127.0.0.1"
-localNodeName = "/Local/Default"
-
-saclGroupNodeName = "/Local/Default"
-saclGroupNames = ("com.apple.access_calendar", "com.apple.access_addressbook")
-
-masterUsers = [
-    (
-        "odtestamanda",
-        {
-            dsattributes.kDS1AttrFirstName : ["Amanda"],
-            dsattributes.kDS1AttrLastName  : ["Test"],
-            dsattributes.kDS1AttrDistinguishedName : ["Amanda Test"],
-            dsattributes.kDSNAttrEMailAddress : ["amanda at example.com"],
-            dsattributes.kDS1AttrGeneratedUID : ["9DC04A70-E6DD-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrUniqueID : ["33300"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["20"],
-        },
-    ),
-    (
-        "odtestbetty",
-        {
-            dsattributes.kDS1AttrFirstName : ["Betty"],
-            dsattributes.kDS1AttrLastName  : ["Test"],
-            dsattributes.kDS1AttrDistinguishedName : ["Betty Test"],
-            dsattributes.kDSNAttrEMailAddress : ["betty at example.com"],
-            dsattributes.kDS1AttrGeneratedUID : ["9DC04A71-E6DD-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrUniqueID : ["33301"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["20"],
-        },
-    ),
-    (
-        "odtestcarlene",
-        {
-            dsattributes.kDS1AttrFirstName : ["Carlene"],
-            dsattributes.kDS1AttrLastName  : ["Test"],
-            dsattributes.kDS1AttrDistinguishedName : ["Carlene Test"],
-            dsattributes.kDSNAttrEMailAddress : ["carlene at example.com"],
-            dsattributes.kDS1AttrGeneratedUID : ["9DC04A72-E6DD-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrUniqueID : ["33302"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["20"],
-        },
-    ),
-    (
-        "odtestdenise",
-        {
-            dsattributes.kDS1AttrFirstName : ["Denise"],
-            dsattributes.kDS1AttrLastName  : ["Test"],
-            dsattributes.kDS1AttrDistinguishedName : ["Denise Test"],
-            dsattributes.kDSNAttrEMailAddress : ["denise at example.com"],
-            dsattributes.kDS1AttrGeneratedUID : ["9DC04A73-E6DD-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrUniqueID : ["33303"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["20"],
-        },
-    ),
-    (
-        "odtestunicode",
-        {
-            dsattributes.kDS1AttrFirstName : ["Unicode " + unichr(208)],
-            dsattributes.kDS1AttrLastName  : ["Test"],
-            dsattributes.kDS1AttrDistinguishedName : ["Unicode Test " + unichr(208)],
-            dsattributes.kDSNAttrEMailAddress : ["unicodetest at example.com"],
-            dsattributes.kDS1AttrGeneratedUID : ["CA795296-D77A-4E09-A72F-869920A3D284"],
-            dsattributes.kDS1AttrUniqueID : ["33304"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["20"],
-        },
-    ),
-    (
-        "odtestat at sign",
-        {
-            dsattributes.kDS1AttrFirstName : ["AtSign"],
-            dsattributes.kDS1AttrLastName  : ["Test"],
-            dsattributes.kDS1AttrDistinguishedName : ["At Sign Test"],
-            dsattributes.kDSNAttrEMailAddress : ["attsign at example.com"],
-            dsattributes.kDS1AttrGeneratedUID : ["71646A3A-1CEF-4744-AB1D-0AC855E25DC8"],
-            dsattributes.kDS1AttrUniqueID : ["33305"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["20"],
-        },
-    ),
-    (
-        "odtestsatou",
-        {
-            dsattributes.kDS1AttrFirstName : ["\xe4\xbd\x90\xe8\x97\xa4\xe4\xbd\x90\xe8\x97\xa4\xe4\xbd\x90\xe8\x97\xa4".decode("utf-8")],
-            dsattributes.kDS1AttrLastName  : ["Test \xe4\xbd\x90\xe8\x97\xa4".decode("utf-8")],
-            dsattributes.kDS1AttrDistinguishedName : ["\xe4\xbd\x90\xe8\x97\xa4\xe4\xbd\x90\xe8\x97\xa4\xe4\xbd\x90\xe8\x97\xa4 Test \xe4\xbd\x90\xe8\x97\xa4".decode("utf-8")],
-            dsattributes.kDSNAttrEMailAddress : ["satou at example.com"],
-            dsattributes.kDS1AttrGeneratedUID : ["C662F833-75AD-4589-9879-5FF102943CEF"],
-            dsattributes.kDS1AttrUniqueID : ["33306"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["20"],
-        },
-    ),
-]
-
-masterGroups = [
-    (
-        "odtestsubgroupb",
-        {
-            dsattributes.kDS1AttrGeneratedUID : ["6C6CD282-E6E3-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrDistinguishedName : ["OD Test Subgroup B"],
-            dsattributes.kDSNAttrGroupMembers : ["9DC04A72-E6DD-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["33401"],
-        },
-    ),
-    (
-        "odtestgrouptop",
-        {
-            dsattributes.kDS1AttrGeneratedUID : ["6C6CD280-E6E3-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrDistinguishedName : ["OD Test Group Top"],
-            dsattributes.kDSNAttrGroupMembers : ["9DC04A70-E6DD-11DF-9492-0800200C9A66", "9DC04A71-E6DD-11DF-9492-0800200C9A66"],
-            dsattributes.kDSNAttrNestedGroups : ["6C6CD282-E6E3-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["33400"],
-        },
-    ),
-]
-
-localUsers = [
-    (
-        "odtestalbert",
-        {
-            dsattributes.kDS1AttrFirstName : ["Albert"],
-            dsattributes.kDS1AttrLastName  : ["Test"],
-            dsattributes.kDS1AttrDistinguishedName : ["Albert Test"],
-            dsattributes.kDSNAttrEMailAddress : ["albert at example.com"],
-            dsattributes.kDS1AttrGeneratedUID : ["9DC04A74-E6DD-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrUniqueID : ["33350"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["20"],
-        },
-    ),
-    (
-        "odtestbill",
-        {
-            dsattributes.kDS1AttrFirstName : ["Bill"],
-            dsattributes.kDS1AttrLastName  : ["Test"],
-            dsattributes.kDS1AttrDistinguishedName : ["Bill Test"],
-            dsattributes.kDSNAttrEMailAddress : ["bill at example.com"],
-            dsattributes.kDS1AttrGeneratedUID : ["9DC04A75-E6DD-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrUniqueID : ["33351"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["20"],
-        },
-    ),
-    (
-        "odtestcarl",
-        {
-            dsattributes.kDS1AttrFirstName : ["Carl"],
-            dsattributes.kDS1AttrLastName  : ["Test"],
-            dsattributes.kDS1AttrDistinguishedName : ["Carl Test"],
-            dsattributes.kDSNAttrEMailAddress : ["carl at example.com"],
-            dsattributes.kDS1AttrGeneratedUID : ["9DC04A76-E6DD-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrUniqueID : ["33352"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["20"],
-        },
-    ),
-    (
-        "odtestdavid",
-        {
-            dsattributes.kDS1AttrFirstName : ["David"],
-            dsattributes.kDS1AttrLastName  : ["Test"],
-            dsattributes.kDS1AttrDistinguishedName : ["David Test"],
-            dsattributes.kDSNAttrEMailAddress : ["david at example.com"],
-            dsattributes.kDS1AttrGeneratedUID : ["9DC04A77-E6DD-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrUniqueID : ["33353"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["20"],
-        },
-    ),
-]
-
-localGroups = [
-    (
-        "odtestsubgroupa",
-        {
-            dsattributes.kDS1AttrGeneratedUID : ["6C6CD281-E6E3-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrDistinguishedName : ["OD Test Subgroup A"],
-            dsattributes.kDSNAttrGroupMembers : ["9DC04A74-E6DD-11DF-9492-0800200C9A66", "9DC04A75-E6DD-11DF-9492-0800200C9A66"],
-            dsattributes.kDS1AttrPrimaryGroupID : ["33402"],
-        },
-    ),
-]
-
-
-def usage(e=None):
-    name = os.path.basename(sys.argv[0])
-    print("usage: %s [options] local_user local_password odmaster_user odmaster_password" % (name,))
-    print("")
-    print(" Configures local and OD master directories for testing")
-    print("")
-    print("options:")
-    print(" -h --help: print this help and exit")
-    if e:
-        sys.exit(1)
-    else:
-        sys.exit(0)
-
-
-def lookupRecordName(node, recordType, name):
-    query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
-        node,
-        recordType,
-        dsattributes.kDSNAttrRecordName,
-        dsattributes.eDSExact,
-        name,
-        None,
-        0,
-        None)
-    if error:
-        raise ODError(error)
-    records, error = query.resultsAllowingPartial_error_(False, None)
-    if error:
-        raise ODError(error)
-
-    if len(records) < 1:
-        return None
-    if len(records) > 1:
-        raise ODError("Multiple records for '%s' were found" % (name,))
-
-    return records[0]
-
-def createRecord(node, recordType, recordName, attrs):
-    record, error = node.createRecordWithRecordType_name_attributes_error_(
-        recordType,
-        recordName,
-        attrs,
-        None)
-    if error:
-        print(error)
-        raise ODError(error)
-    return record
-
-def main():
-
-    try:
-        (optargs, args) = getopt(sys.argv[1:], "h", ["help"])
-    except GetoptError, e:
-        usage(e)
-
-    for opt, arg in optargs:
-        if opt in ("-h", "--help"):
-            usage()
-
-    if len(args) != 4:
-        usage()
-
-    localUser, localPassword, masterUser, masterPassword = args
-
-    userInfo = {
-        masterNodeName : {
-            "user" : masterUser,
-            "password" : masterPassword,
-            "users" : masterUsers,
-            "groups" : masterGroups,
-        },
-        localNodeName : {
-            "user" : localUser,
-            "password" : localPassword,
-            "users" : localUsers,
-            "groups" : localGroups,
-        },
-    }
-
-
-
-    session = odframework.ODSession.defaultSession()
-    userRecords = []
-
-    for nodeName, info in userInfo.iteritems():
-
-        userName = info["user"]
-        password = info["password"]
-        users = info["users"]
-        groups = info["groups"]
-
-        node, error = odframework.ODNode.nodeWithSession_name_error_(session, nodeName, None)
-        if error:
-            print(error)
-            raise ODError(error)
-
-        result, error = node.setCredentialsWithRecordType_recordName_password_error_(
-            dsattributes.kDSStdRecordTypeUsers,
-            userName,
-            password,
-            None
-        )
-        if error:
-            print("Unable to authenticate with directory %s: %s" % (nodeName, error))
-            raise ODError(error)
-
-        print("Successfully authenticated with directory %s" % (nodeName,))
-
-        print("Creating users within %s:" % (nodeName,))
-        for recordName, attrs in users:
-            record = lookupRecordName(node, dsattributes.kDSStdRecordTypeUsers, recordName)
-            if record is None:
-                print("Creating user %s" % (recordName,))
-                try:
-                    record = createRecord(node, dsattributes.kDSStdRecordTypeUsers, recordName, attrs)
-                    print("Successfully created user %s" % (recordName,))
-                    result, error = record.changePassword_toPassword_error_(
-                        None, "password", None)
-                    if error or not result:
-                        print("Failed to set password for %s: %s" % (recordName, error))
-                    else:
-                        print("Successfully set password for %s" % (recordName,))
-                except ODError, e:
-                    print("Failed to create user %s: %s" % (recordName, e))
-            else:
-                print("User %s already exists" % (recordName,))
-
-            if record is not None:
-                userRecords.append(record)
-
-        print("Creating groups within %s:" % (nodeName,))
-        for recordName, attrs in groups:
-            record = lookupRecordName(node, dsattributes.kDSStdRecordTypeGroups, recordName)
-            if record is None:
-                print("Creating group %s" % (recordName,))
-                try:
-                    record = createRecord(node, dsattributes.kDSStdRecordTypeGroups, recordName, attrs)
-                    print("Successfully created group %s" % (recordName,))
-                except ODError, e:
-                    print("Failed to create group %s: %s" % (recordName, e))
-            else:
-                print("Group %s already exists" % (recordName,))
-
-        print
-
-    # Populate SACL groups
-    node, error = odframework.ODNode.nodeWithSession_name_error_(session, saclGroupNodeName, None)
-    result, error = node.setCredentialsWithRecordType_recordName_password_error_(
-        dsattributes.kDSStdRecordTypeUsers,
-        userInfo[saclGroupNodeName]["user"],
-        userInfo[saclGroupNodeName]["password"],
-        None
-    )
-    if not error:
-        for saclGroupName in saclGroupNames:
-            saclGroupRecord = lookupRecordName(node, dsattributes.kDSStdRecordTypeGroups, saclGroupName)
-            if saclGroupRecord:
-                print("Populating %s SACL group:" % (saclGroupName,))
-                for userRecord in userRecords:
-                    details, error = userRecord.recordDetailsForAttributes_error_(None, None)
-                    recordName = details.get(dsattributes.kDSNAttrRecordName, [None])[0]
-                    result, error = saclGroupRecord.isMemberRecord_error_(userRecord, None)
-                    if result:
-                        print("%s is already in the %s SACL group" % (recordName, saclGroupName))
-                    else:
-                        result, error = saclGroupRecord.addMemberRecord_error_(userRecord, None)
-                        print("Adding %s to the %s SACL group" % (recordName, saclGroupName))
-
-            print("")
-
-class ODError(Exception):
-    def __init__(self, error):
-        self.message = (str(error), error.code())
-
-if __name__ == "__main__":
-    main()

Deleted: twext/trunk/twext/who/opendirectory/setup_testusers.py
===================================================================
--- twext/trunk/twext/who/opendirectory/setup_testusers.py	2013-12-18 00:50:59 UTC (rev 12126)
+++ twext/trunk/twext/who/opendirectory/setup_testusers.py	2013-12-18 18:29:24 UTC (rev 12127)
@@ -1,145 +0,0 @@
-##
-# Copyright (c) 2012-2013 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-from __future__ import print_function
-
-import os
-import sys
-import odframework
-import dsattributes
-from getopt import getopt, GetoptError
-
-
-def usage(e=None):
-    name = os.path.basename(sys.argv[0])
-    print("usage: %s [options] local_user local_password" % (name,))
-    print("")
-    print(" Configures local directory for test users")
-    print("")
-    print("options:")
-    print(" -h --help: print this help and exit")
-    if e:
-        sys.exit(1)
-    else:
-        sys.exit(0)
-
-
-def lookupRecordName(node, recordType, name):
-    query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
-        node,
-        recordType,
-        dsattributes.kDSNAttrRecordName,
-        dsattributes.eDSExact,
-        name,
-        None,
-        0,
-        None)
-    if error:
-        raise ODError(error)
-    records, error = query.resultsAllowingPartial_error_(False, None)
-    if error:
-        raise ODError(error)
-
-    if len(records) < 1:
-        return None
-    if len(records) > 1:
-        raise ODError("Multiple records for '%s' were found" % (name,))
-
-    return records[0]
-
-def createRecord(node, recordType, recordName, attrs):
-    record, error = node.createRecordWithRecordType_name_attributes_error_(
-        recordType,
-        recordName,
-        attrs,
-        None)
-    if error:
-        print(error)
-        raise ODError(error)
-    return record
-
-def main():
-
-    try:
-        (optargs, args) = getopt(sys.argv[1:], "h", ["help"])
-    except GetoptError, e:
-        usage(e)
-
-    for opt, arg in optargs:
-        if opt in ("-h", "--help"):
-            usage()
-
-    if len(args) != 2:
-        usage()
-
-    localUser, localPassword = args
-
-    session = odframework.ODSession.defaultSession()
-
-    nodeName = "/Local/Default"
-    node, error = odframework.ODNode.nodeWithSession_name_error_(session, nodeName, None)
-    if error:
-        print(error)
-        raise ODError(error)
-
-    result, error = node.setCredentialsWithRecordType_recordName_password_error_(
-        dsattributes.kDSStdRecordTypeUsers,
-        localUser,
-        localPassword,
-        None
-    )
-    if error:
-        print("Unable to authenticate with directory %s: %s" % (nodeName, error))
-        raise ODError(error)
-
-    print("Successfully authenticated with directory %s" % (nodeName,))
-
-    print("Creating users within %s:" % (nodeName,))
-    for i in xrange(99):
-        j = i+1
-        recordName = "user%02d" % (j,)
-        password = "user%02d" % (j,)
-        attrs = {
-            dsattributes.kDS1AttrFirstName : ["User"],
-            dsattributes.kDS1AttrLastName  : ["%02d" % (j,)],
-            dsattributes.kDS1AttrDistinguishedName : ["User %02d" % (j,)],
-            dsattributes.kDSNAttrEMailAddress : ["user%02d at example.com" % (j,)],
-            dsattributes.kDS1AttrGeneratedUID : ["user%02d" % (j,)],
-        }
-
-        record = lookupRecordName(node, dsattributes.kDSStdRecordTypeUsers, recordName)
-        if record is None:
-            print("Creating user %s" % (recordName,))
-            try:
-                record = createRecord(node, dsattributes.kDSStdRecordTypeUsers, recordName, attrs)
-                print("Successfully created user %s" % (recordName,))
-                result, error = record.changePassword_toPassword_error_(
-                    None, password, None)
-                if error or not result:
-                    print("Failed to set password for %s: %s" % (recordName, error))
-                else:
-                    print("Successfully set password for %s" % (recordName,))
-            except ODError, e:
-                print("Failed to create user %s: %s" % (recordName, e))
-        else:
-            print("User %s already exists" % (recordName,))
-
-
-class ODError(Exception):
-    def __init__(self, error):
-        self.message = (str(error), error.code())
-
-if __name__ == "__main__":
-    main()

Deleted: twext/trunk/twext/who/opendirectory/test/test_opendirectory.py
===================================================================
--- twext/trunk/twext/who/opendirectory/test/test_opendirectory.py	2013-12-18 00:50:59 UTC (rev 12126)
+++ twext/trunk/twext/who/opendirectory/test/test_opendirectory.py	2013-12-18 18:29:24 UTC (rev 12127)
@@ -1,940 +0,0 @@
-##
-# Copyright (c) 2010-2013 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-from __future__ import print_function
-
-from twistedcaldav.test.util import TestCase
-import hashlib
-import random
-import sys
-
-runTests = False
-
-try:
-    from calendarserver.platform.darwin.od import opendirectory, dsattributes, dsquery, setup_directory
-
-    directory = opendirectory.odInit("/Search")
-
-    results = opendirectory.queryRecordsWithAttribute_list(
-        directory,
-        dsattributes.kDS1AttrGeneratedUID,
-        "9DC04A74-E6DD-11DF-9492-0800200C9A66",
-        dsattributes.eDSExact,
-        False,
-        dsattributes.kDSStdRecordTypeUsers,
-        None,
-        count=0
-    )
-    recordNames = [x[0] for x in results]
-    # Local user:
-    if "odtestalbert" in recordNames:
-        runTests = True
-    else:
-        print("Please run setup_directory.py to populate OD")
-
-except ImportError:
-    print("Unable to import OpenDirectory framework")
-
-
-def generateNonce():
-    c = tuple([random.randrange(sys.maxint) for _ in range(3)])
-    c = '%d%d%d' % c
-    return c
-
-def getChallengeResponse(user, password, node, uri, method):
-    nonce = generateNonce()
-
-    ha1 = hashlib.md5("%s:%s:%s" % (user, node, password)).hexdigest()
-    ha2 = hashlib.md5("%s:%s" % (method, uri)).hexdigest()
-    response = hashlib.md5("%s:%s:%s"% (ha1, nonce, ha2)).hexdigest()
-
-    fields = {
-        'username': user,
-        'nonce': nonce,
-        'realm': node,
-        'algorithm': 'md5',
-        'uri': uri,
-        'response': response,
-    }
-
-    challenge = 'Digest realm="%(realm)s", nonce="%(nonce)s", algorithm=%(algorithm)s' % fields
-
-    response = (
-        'Digest username="%(username)s", '
-        'realm="%(realm)s", '
-        'nonce="%(nonce)s", '
-        'uri="%(uri)s", '
-        'response="%(response)s",'
-        'algorithm=%(algorithm)s'
-    ) % fields
-
-    return challenge, response
-
-if runTests:
-
-    USER_ATTRIBUTES = [
-        dsattributes.kDS1AttrGeneratedUID,
-        dsattributes.kDSNAttrRecordName,
-        dsattributes.kDSNAttrAltSecurityIdentities,
-        dsattributes.kDSNAttrRecordType,
-        dsattributes.kDS1AttrDistinguishedName,
-        dsattributes.kDS1AttrFirstName,
-        dsattributes.kDS1AttrLastName,
-        dsattributes.kDSNAttrEMailAddress,
-        dsattributes.kDSNAttrMetaNodeLocation,
-        (dsattributes.kDSNAttrJPEGPhoto, "base64"),
-    ]
-
-    class OpenDirectoryTests(TestCase):
-
-        def test_odInit(self):
-
-            # Bogus node name
-            self.assertRaises(opendirectory.ODError, opendirectory.odInit, "/Foo")
-
-            # Valid node name
-            directory = opendirectory.odInit("/Search")
-            self.assertTrue(isinstance(directory, opendirectory.Directory))
-
-        def test_adjustMatchType(self):
-            self.assertEquals(
-                opendirectory.adjustMatchType(dsattributes.eDSExact, False),
-                dsattributes.eDSExact
-            )
-            self.assertEquals(
-                opendirectory.adjustMatchType(dsattributes.eDSExact, True),
-                dsattributes.eDSExact | 0x100
-            )
-
-        def test_getNodeAttributes(self):
-
-            directory = opendirectory.odInit("/Search")
-            results = opendirectory.getNodeAttributes(directory, "/Search", [dsattributes.kDS1AttrSearchPath])
-            self.assertTrue("/Local/Default" in results[dsattributes.kDS1AttrSearchPath])
-            self.assertTrue("/LDAPv3/127.0.0.1" in results[dsattributes.kDS1AttrSearchPath])
-
-        def test_listAllRecordsWithAttributes_list_master(self):
-
-            directory = opendirectory.odInit("/LDAPv3/127.0.0.1")
-            results = opendirectory.listAllRecordsWithAttributes_list(
-                directory,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            for recordName, info in setup_directory.masterUsers:
-                self.assertTrue(recordName in recordNames)
-
-        def test_listAllRecordsWithAttributes_list_local(self):
-
-            directory = opendirectory.odInit("/Local/Default")
-            results = opendirectory.listAllRecordsWithAttributes_list(
-                directory,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            for recordName, info in setup_directory.localUsers:
-                self.assertTrue(recordName in recordNames)
-
-
-        def test_queryRecordsWithAttribute_list_firstname_exact_insensitive_match(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrFirstName,
-                "betty",
-                dsattributes.eDSExact,
-                False,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertTrue("odtestbetty" in recordNames)
-
-        def test_queryRecordsWithAttribute_list_firstname_exact_insensitive_match_multitype(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrFirstName,
-                "betty",
-                dsattributes.eDSExact,
-                False,
-                [
-                    dsattributes.kDSStdRecordTypeUsers,
-                    dsattributes.kDSStdRecordTypeGroups,
-                    dsattributes.kDSStdRecordTypeResources,
-                    dsattributes.kDSStdRecordTypePlaces,
-                ],
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertTrue("odtestbetty" in recordNames)
-
-        def test_queryRecordsWithAttribute_list_firstname_begins_insensitive_match(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrFirstName,
-                "Amand",
-                dsattributes.eDSStartsWith,
-                True,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertTrue("odtestamanda" in recordNames)
-
-        def test_queryRecordsWithAttribute_list_firstname_begins_insensitive_match_multitype(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrFirstName,
-                "Amand",
-                dsattributes.eDSStartsWith,
-                True,
-                [
-                    dsattributes.kDSStdRecordTypeUsers,
-                    dsattributes.kDSStdRecordTypeGroups,
-                    dsattributes.kDSStdRecordTypeResources,
-                    dsattributes.kDSStdRecordTypePlaces,
-                ],
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertTrue("odtestamanda" in recordNames)
-
-        def test_queryRecordsWithAttribute_list_firstname_contains_insensitive_match(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrFirstName,
-                "mand",
-                dsattributes.eDSContains,
-                True,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertTrue("odtestamanda" in recordNames)
-
-        def test_queryRecordsWithAttribute_list_firstname_contains_insensitive_match_multitype(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrFirstName,
-                "mand",
-                dsattributes.eDSContains,
-                True,
-                [
-                    dsattributes.kDSStdRecordTypeUsers,
-                    dsattributes.kDSStdRecordTypeGroups,
-                    dsattributes.kDSStdRecordTypeResources,
-                    dsattributes.kDSStdRecordTypePlaces,
-                ],
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertTrue("odtestamanda" in recordNames)
-
-        def test_queryRecordsWithAttribute_list_lastname_exact_insensitive_match(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrLastName,
-                "test",
-                dsattributes.eDSExact,
-                True,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            for recordName, info in setup_directory.masterUsers:
-                if info[dsattributes.kDS1AttrLastName] == "Test":
-                    self.assertTrue(recordName in recordNames)
-            for recordName, info in setup_directory.localUsers:
-                if info[dsattributes.kDS1AttrLastName] == "Test":
-                    self.assertTrue(recordName in recordNames)
-
-        def test_queryRecordsWithAttribute_list_lastname_exact_insensitive_match_multitype(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrLastName,
-                "test",
-                dsattributes.eDSExact,
-                True,
-                [
-                    dsattributes.kDSStdRecordTypeUsers,
-                    dsattributes.kDSStdRecordTypeGroups,
-                    dsattributes.kDSStdRecordTypeResources,
-                    dsattributes.kDSStdRecordTypePlaces,
-                ],
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            for recordName, info in setup_directory.masterUsers:
-                if info[dsattributes.kDS1AttrLastName] == "Test":
-                    self.assertTrue(recordName in recordNames)
-            for recordName, info in setup_directory.localUsers:
-                if info[dsattributes.kDS1AttrLastName] == "Test":
-                    self.assertTrue(recordName in recordNames)
-
-        def test_queryRecordsWithAttribute_list_lastname_begins_insensitive_match(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrLastName,
-                "tes",
-                dsattributes.eDSStartsWith,
-                True,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            for recordName, info in setup_directory.masterUsers:
-                self.assertTrue(recordName in recordNames)
-            for recordName, info in setup_directory.localUsers:
-                self.assertTrue(recordName in recordNames)
-
-        def test_queryRecordsWithAttribute_list_lastname_begins_insensitive_match_multitype(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrLastName,
-                "tes",
-                dsattributes.eDSStartsWith,
-                True,
-                [
-                    dsattributes.kDSStdRecordTypeUsers,
-                    dsattributes.kDSStdRecordTypeGroups,
-                    dsattributes.kDSStdRecordTypeResources,
-                    dsattributes.kDSStdRecordTypePlaces,
-                ],
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            for recordName, info in setup_directory.masterUsers:
-                self.assertTrue(recordName in recordNames)
-            for recordName, info in setup_directory.localUsers:
-                self.assertTrue(recordName in recordNames)
-
-        def test_queryRecordsWithAttribute_list_lastname_contains_insensitive_match(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrLastName,
-                "es",
-                dsattributes.eDSContains,
-                True,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            for recordName, info in setup_directory.masterUsers:
-                self.assertTrue(recordName in recordNames)
-            for recordName, info in setup_directory.localUsers:
-                self.assertTrue(recordName in recordNames)
-
-        def test_queryRecordsWithAttribute_list_lastname_contains_insensitive_match_multitype(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrLastName,
-                "es",
-                dsattributes.eDSContains,
-                True,
-                [
-                    dsattributes.kDSStdRecordTypeUsers,
-                    dsattributes.kDSStdRecordTypeGroups,
-                    dsattributes.kDSStdRecordTypeResources,
-                    dsattributes.kDSStdRecordTypePlaces,
-                ],
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            for recordName, info in setup_directory.masterUsers:
-                self.assertTrue(recordName in recordNames)
-            for recordName, info in setup_directory.localUsers:
-                self.assertTrue(recordName in recordNames)
-
-        def test_queryRecordsWithAttribute_list_email_begins_insensitive_match(self):
-            # This test won't pass until this is fixed: <rdar://problem/8608148>
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDSNAttrEMailAddress,
-                "aman",
-                dsattributes.eDSStartsWith,
-                True,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertTrue("odtestamanda" in recordNames)
-
-
-        def test_queryRecordsWithAttribute_list_email_begins_insensitive_match_multitype(self):
-            # This test won't pass until this is fixed: <rdar://problem/8608148>
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDSNAttrEMailAddress,
-                "aman",
-                dsattributes.eDSStartsWith,
-                True,
-                [
-                    dsattributes.kDSStdRecordTypeUsers,
-                    dsattributes.kDSStdRecordTypeGroups,
-                    dsattributes.kDSStdRecordTypeResources,
-                    dsattributes.kDSStdRecordTypePlaces,
-                ],
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertTrue("odtestamanda" in recordNames)
-
-
-
-        def test_queryRecordsWithAttribute_list_guid_exact_sensitive_match_master(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrGeneratedUID,
-                "9DC04A70-E6DD-11DF-9492-0800200C9A66",
-                dsattributes.eDSExact,
-                False,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            # OD Master user:
-            self.assertTrue("odtestamanda" in recordNames)
-
-        def test_queryRecordsWithAttribute_list_guid_exact_sensitive_match_multitype_master(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrGeneratedUID,
-                "9DC04A70-E6DD-11DF-9492-0800200C9A66",
-                dsattributes.eDSExact,
-                False,
-                [
-                    dsattributes.kDSStdRecordTypeUsers,
-                    dsattributes.kDSStdRecordTypeGroups,
-                    dsattributes.kDSStdRecordTypeResources,
-                    dsattributes.kDSStdRecordTypePlaces,
-                ],
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            # OD Master user:
-            self.assertTrue("odtestamanda" in recordNames)
-
-
-        def test_queryRecordsWithAttribute_list_guid_exact_sensitive_match_local(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrGeneratedUID,
-                "9DC04A74-E6DD-11DF-9492-0800200C9A66",
-                dsattributes.eDSExact,
-                False,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            # Local user:
-            self.assertTrue("odtestalbert" in recordNames)
-
-
-        def test_queryRecordsWithAttribute_list_guid_exact_sensitive_match_multitype_local(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrGeneratedUID,
-                "9DC04A74-E6DD-11DF-9492-0800200C9A66",
-                dsattributes.eDSExact,
-                False,
-                [
-                    dsattributes.kDSStdRecordTypeUsers,
-                    dsattributes.kDSStdRecordTypeGroups,
-                    dsattributes.kDSStdRecordTypeResources,
-                    dsattributes.kDSStdRecordTypePlaces,
-                ],
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            # Local user:
-            self.assertTrue("odtestalbert" in recordNames)
-
-
-
-        def test_queryRecordsWithAttribute_list_groupMembers_recordName_master(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDSNAttrRecordName,
-                "odtestgrouptop",
-                dsattributes.eDSExact,
-                False,
-                dsattributes.kDSStdRecordTypeGroups,
-                [
-                    dsattributes.kDSNAttrGroupMembers,
-                    dsattributes.kDSNAttrNestedGroups,
-                ],
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertTrue("odtestgrouptop" in recordNames)
-            groupMembers = results[0][1][dsattributes.kDSNAttrGroupMembers]
-            self.assertEquals(
-                set(groupMembers),
-                set(setup_directory.masterGroups[1][1][dsattributes.kDSNAttrGroupMembers])
-            )
-
-        def test_queryRecordsWithAttribute_list_groupMembers_recordName_local(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDSNAttrRecordName,
-                "odtestsubgroupa",
-                dsattributes.eDSExact,
-                False,
-                dsattributes.kDSStdRecordTypeGroups,
-                [
-                    dsattributes.kDSNAttrGroupMembers,
-                    dsattributes.kDSNAttrNestedGroups,
-                ],
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertTrue("odtestsubgroupa" in recordNames)
-            groupMembers = results[0][1][dsattributes.kDSNAttrGroupMembers]
-            self.assertEquals(
-                set(groupMembers),
-                set(setup_directory.localGroups[0][1][dsattributes.kDSNAttrGroupMembers])
-            )
-
-
-        def test_queryRecordsWithAttribute_list_groupMembers_guid_master(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrGeneratedUID,
-                "6C6CD280-E6E3-11DF-9492-0800200C9A66",
-                dsattributes.eDSExact,
-                False,
-                dsattributes.kDSStdRecordTypeGroups,
-                [
-                    dsattributes.kDSNAttrGroupMembers,
-                    dsattributes.kDSNAttrNestedGroups,
-                ],
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertTrue("odtestgrouptop" in recordNames)
-            groupMembers = results[0][1][dsattributes.kDSNAttrGroupMembers]
-            self.assertEquals(
-                set(groupMembers),
-                set(setup_directory.masterGroups[1][1][dsattributes.kDSNAttrGroupMembers])
-            )
-
-        def test_queryRecordsWithAttribute_list_groupMembers_guid_local(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrGeneratedUID,
-                "6C6CD281-E6E3-11DF-9492-0800200C9A66",
-                dsattributes.eDSExact,
-                False,
-                dsattributes.kDSStdRecordTypeGroups,
-                [
-                    dsattributes.kDSNAttrGroupMembers,
-                    dsattributes.kDSNAttrNestedGroups,
-                ],
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertTrue("odtestsubgroupa" in recordNames)
-            groupMembers = results[0][1][dsattributes.kDSNAttrGroupMembers]
-            self.assertEquals(
-                groupMembers,
-                setup_directory.localGroups[0][1][dsattributes.kDSNAttrGroupMembers]
-            )
-
-
-        def test_queryRecordsWithAttribute_list_groupsForGUID(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDSNAttrGroupMembers,
-                "9DC04A70-E6DD-11DF-9492-0800200C9A66",
-                dsattributes.eDSExact,
-                False,
-                dsattributes.kDSStdRecordTypeGroups,
-                [
-                    dsattributes.kDS1AttrGeneratedUID,
-                ],
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertTrue("odtestgrouptop" in recordNames)
-
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDSNAttrNestedGroups,
-                "9DC04A70-E6DD-11DF-9492-0800200C9A66",
-                dsattributes.eDSExact,
-                False,
-                dsattributes.kDSStdRecordTypeGroups,
-                [
-                    dsattributes.kDS1AttrGeneratedUID,
-                ],
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            self.assertEquals([], recordNames)
-
-        def test_queryRecordsWithAttributes_list_master(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            expressions = [
-                dsquery.match(dsattributes.kDS1AttrDistinguishedName, "aman", "starts-with"),
-                dsquery.match(dsattributes.kDS1AttrFirstName, "amanda", "equals"),
-                dsquery.match(dsattributes.kDS1AttrLastName, "es", "contains"),
-                dsquery.match(dsattributes.kDSNAttrEMailAddress, "amanda@", "starts-with"),
-            ]
-
-            compound = dsquery.expression(dsquery.expression.OR, expressions).generate()
-
-            results = opendirectory.queryRecordsWithAttributes_list(
-                directory,
-                compound,
-                True,
-                [
-                    dsattributes.kDSStdRecordTypeUsers,
-                    dsattributes.kDSStdRecordTypeGroups,
-                    dsattributes.kDSStdRecordTypeResources,
-                    dsattributes.kDSStdRecordTypePlaces,
-                ],
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            # Master user:
-            self.assertTrue("odtestamanda" in recordNames)
-
-        def test_queryRecordsWithAttributes_list_nonascii(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            expressions = [
-                dsquery.match(dsattributes.kDS1AttrFirstName, "\xe4\xbd\x90", "contains"),
-                dsquery.match(dsattributes.kDS1AttrLastName, "Test", "contains"),
-            ]
-
-            compound = dsquery.expression(dsquery.expression.AND, expressions).generate()
-
-            results = opendirectory.queryRecordsWithAttributes_list(
-                directory,
-                compound,
-                True,
-                [
-                    dsattributes.kDSStdRecordTypeUsers,
-                    dsattributes.kDSStdRecordTypeGroups,
-                    dsattributes.kDSStdRecordTypeResources,
-                    dsattributes.kDSStdRecordTypePlaces,
-                ],
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            # Master user:
-            self.assertTrue("odtestsatou" in recordNames)
-
-
-        def test_queryRecordsWithAttributes_list_local(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            expressions = [
-                dsquery.match(dsattributes.kDS1AttrDistinguishedName, "bil", "starts-with"),
-                dsquery.match(dsattributes.kDS1AttrFirstName, "Bill", "equals"),
-                dsquery.match(dsattributes.kDS1AttrLastName, "es", "contains"),
-                dsquery.match(dsattributes.kDSNAttrEMailAddress, "bill@", "starts-with"),
-            ]
-
-            compound = dsquery.expression(dsquery.expression.OR, expressions).generate()
-
-            results = opendirectory.queryRecordsWithAttributes_list(
-                directory,
-                compound,
-                True,
-                [
-                    dsattributes.kDSStdRecordTypeUsers,
-                    dsattributes.kDSStdRecordTypeGroups,
-                    dsattributes.kDSStdRecordTypeResources,
-                    dsattributes.kDSStdRecordTypePlaces,
-                ],
-                USER_ATTRIBUTES,
-                count=0
-            )
-            recordNames = [x[0] for x in results]
-            # Local user:
-            self.assertTrue("odtestbill" in recordNames)
-
-
-        def test_getUserRecord_existing(self):
-            directory = opendirectory.odInit("/Search")
-            record = opendirectory.getUserRecord(directory, "odtestbill")
-            self.assertNotEquals(record, None)
-
-        def test_getUserRecord_missing(self):
-            directory = opendirectory.odInit("/Search")
-            record = opendirectory.getUserRecord(directory, "i_do_not_exist")
-            self.assertEquals(record, None)
-
-        def test_basicAuth_master(self):
-            directory = opendirectory.odInit("/Search")
-            result = opendirectory.authenticateUserBasic(directory,
-                "/LDAPv3/127.0.0.1", "odtestamanda", "password")
-            self.assertTrue(result)
-
-        def test_basicAuth_local(self):
-            directory = opendirectory.odInit("/Search")
-            result = opendirectory.authenticateUserBasic(directory,
-                "/Local/Default", "odtestalbert", "password")
-            self.assertTrue(result)
-
-        def test_digestAuth_master(self):
-            directory = opendirectory.odInit("/Search")
-
-            user = "odtestamanda"
-            password = "password"
-            node = "/LDAPv3/127.0.0.1"
-            uri = "principals/users/odtestamanda"
-            method = "PROPFIND"
-
-            challenge, response = getChallengeResponse(user, password, node,
-                uri, method)
-
-            result = opendirectory.authenticateUserDigest(directory, node,
-                user, challenge, response, method)
-            self.assertTrue(result)
-
-        def test_digestAuth_master_wrong_password(self):
-            directory = opendirectory.odInit("/Search")
-
-            user = "odtestamanda"
-            password = "wrong"
-            node = "/LDAPv3/127.0.0.1"
-            uri = "principals/users/odtestamanda"
-            method = "PROPFIND"
-
-            challenge, response = getChallengeResponse(user, password, node,
-                uri, method)
-
-            self.assertEquals(
-                False,
-                opendirectory.authenticateUserDigest(directory, node, user,
-                    challenge, response, method)
-            )
-
-        def test_digestAuth_master_missing_record(self):
-            directory = opendirectory.odInit("/Search")
-
-            user = "missingperson"
-            password = "wrong"
-            node = "/LDAPv3/127.0.0.1"
-            uri = "principals/users/odtestamanda"
-            method = "PROPFIND"
-
-            challenge, response = getChallengeResponse(user, password, node,
-                uri, method)
-
-            self.assertRaises(opendirectory.ODError,
-                opendirectory.authenticateUserDigest,
-                directory, node, user, challenge, response, method)
-
-        def test_digestAuth_local(self):
-            directory = opendirectory.odInit("/Search")
-
-            user = "odtestalbert"
-            password = "password"
-            node = "/Local/Default"
-            uri = "principals/users/odtestalbert"
-            method = "PROPFIND"
-
-            challenge, response = getChallengeResponse(user, password, node,
-                uri, method)
-
-            result = opendirectory.authenticateUserDigest(directory, node,
-                user, challenge, response, method)
-            self.assertTrue(result)
-
-        def test_result_types(self):
-            directory = opendirectory.odInit("/Search")
-            record = opendirectory.getUserRecord(directory, "odtestbill")
-            name, data = opendirectory.recordToResult(record, {})
-            for value in data.values():
-                if isinstance(value, list):
-                    for item in value:
-                        self.assertTrue(type(item) is str)
-                else:
-                    self.assertTrue(type(value) is str)
-
-        def test_nonascii_record_by_guid(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrGeneratedUID,
-                "CA795296-D77A-4E09-A72F-869920A3D284",
-                dsattributes.eDSExact,
-                False,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            result = results[0][1]
-            self.assertEquals(
-                result[dsattributes.kDS1AttrDistinguishedName],
-                "Unicode Test \xc3\x90"
-            )
-
-        def test_nonascii_record_by_name(self):
-
-            directory = opendirectory.odInit("/Search")
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrDistinguishedName,
-                "Unicode Test \xc3\x90",
-                dsattributes.eDSExact,
-                False,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            result = results[0][1]
-            self.assertEquals(
-                result[dsattributes.kDS1AttrGeneratedUID],
-                "CA795296-D77A-4E09-A72F-869920A3D284"
-            )
-
-            results = opendirectory.queryRecordsWithAttribute_list(
-                directory,
-                dsattributes.kDS1AttrFirstName,
-                "\xe4\xbd\x90\xe8\x97\xa4",
-                dsattributes.eDSStartsWith,
-                False,
-                dsattributes.kDSStdRecordTypeUsers,
-                USER_ATTRIBUTES,
-                count=0
-            )
-            result = results[0][1]
-            self.assertEquals(
-                result[dsattributes.kDS1AttrGeneratedUID],
-                "C662F833-75AD-4589-9879-5FF102943CEF"
-            )
-
-        def test_attributeNamesFromList(self):
-            self.assertEquals(
-                ([], {}), opendirectory.attributeNamesFromList(None)
-            )
-            self.assertEquals(
-                (["a", "b"], {"b":"base64"}),
-                opendirectory.attributeNamesFromList(["a", ("b", "base64")])
-            )
-
-        def test_autoPooled(self):
-            """
-            Make sure no exception is raised by an autoPooled method
-            """
-            @opendirectory.autoPooled
-            def method(x):
-                return x + 1
-
-            self.assertEquals(2, method(1))

Modified: twext/trunk/twext/who/opendirectory/test/test_service.py
===================================================================
--- twext/trunk/twext/who/opendirectory/test/test_service.py	2013-12-18 00:50:59 UTC (rev 12126)
+++ twext/trunk/twext/who/opendirectory/test/test_service.py	2013-12-18 18:29:24 UTC (rev 12127)
@@ -35,33 +35,79 @@
 
     def test_queryStringFromExpression(self):
         service = DirectoryService()
-        expression = MatchExpression(
-            service.fieldName.shortNames, u"xyzzy",
-            matchType=MatchType.equals
-        )
-        query = service._queryStringFromExpression(expression)
-        self.assertEquals(query, u"(dsAttrTypeStandard:RecordName=xyzzy)")
 
+        # MatchExpressions
+
+        for matchType, expected in (
+            (MatchType.equals, u"=xyzzy"),
+            (MatchType.startsWith, u"=xyzzy*"),
+            (MatchType.endsWith, u"=*xyzzy"),
+            (MatchType.contains, u"=*xyzzy*"),
+        ):
+            expression = MatchExpression(
+                service.fieldName.shortNames, u"xyzzy",
+                matchType=matchType
+            )
+            queryString = service._queryStringFromExpression(expression)
+            self.assertEquals(queryString,
+                u"(dsAttrTypeStandard:RecordName{exp})".format(exp=expected))
+
+        # CompoundExpressions
+
         expression = CompoundExpression(
             [
                 MatchExpression(
-                    service.fieldName.shortNames, u"xyzzy",
+                    service.fieldName.uid, u"a",
                     matchType=MatchType.contains
                 ),
                 MatchExpression(
-                    service.fieldName.emailAddresses, u"plugh",
+                    service.fieldName.guid, u"b",
+                    matchType=MatchType.contains
+                ),
+                MatchExpression(
+                    service.fieldName.shortNames, u"c",
+                    matchType=MatchType.contains
+                ),
+                MatchExpression(
+                    service.fieldName.emailAddresses, u"d",
                     matchType=MatchType.startsWith
                 ),
                 MatchExpression(
-                    service.fieldName.fullNames, u"foo",
+                    service.fieldName.fullNames, u"e",
                     matchType=MatchType.equals
                 ),
             ],
             Operand.AND
         ) 
-        query = service._queryStringFromExpression(expression)
-        self.assertEquals(query,
-            u"(&(dsAttrTypeStandard:RecordName=*xyzzy*)"
-             "(dsAttrTypeStandard:EMailAddress=plugh*)"
-             "(dsAttrTypeStandard:RealName=foo))"
+        queryString = service._queryStringFromExpression(expression)
+        self.assertEquals(queryString,
+            u"(&(dsAttrTypeStandard:GeneratedUID=*a*)"
+             "(dsAttrTypeStandard:GeneratedUID=*b*)"
+             "(dsAttrTypeStandard:RecordName=*c*)"
+             "(dsAttrTypeStandard:EMailAddress=d*)"
+             "(dsAttrTypeStandard:RealName=e))"
         )
+
+        expression = CompoundExpression(
+            [
+                MatchExpression(
+                    service.fieldName.shortNames, u"a",
+                    matchType=MatchType.contains
+                ),
+                MatchExpression(
+                    service.fieldName.emailAddresses, u"b",
+                    matchType=MatchType.startsWith
+                ),
+                MatchExpression(
+                    service.fieldName.fullNames, u"c",
+                    matchType=MatchType.equals
+                ),
+            ],
+            Operand.OR
+        ) 
+        queryString = service._queryStringFromExpression(expression)
+        self.assertEquals(queryString,
+            u"(|(dsAttrTypeStandard:RecordName=*a*)"
+             "(dsAttrTypeStandard:EMailAddress=b*)"
+             "(dsAttrTypeStandard:RealName=c))"
+        )
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140312/f0d022b7/attachment.html>


More information about the calendarserver-changes mailing list