<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[12596] CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.calendarserver.org//changeset/12596">12596</a></dd>
<dt>Author</dt> <dd>wsanchez@apple.com</dd>
<dt>Date</dt> <dd>2014-02-06 15:36:27 -0800 (Thu, 06 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>logging fixes, lint</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServertrunktwistedcaldavdirectoryldapdirectorypy">CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServertrunktwistedcaldavdirectoryldapdirectorypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py (12595 => 12596)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py        2014-02-06 22:50:28 UTC (rev 12595)
+++ CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py        2014-02-06 23:36:27 UTC (rev 12596)
</span><span class="lines">@@ -314,17 +314,21 @@
</span><span class="cx">             filterstr = &quot;(&amp;%s%s)&quot; % (filterstr, typeFilter)
</span><span class="cx"> 
</span><span class="cx">         # Query the LDAP server
</span><del>-        self.log.debug(&quot;Querying ldap for records matching base {base} and &quot;
-                       &quot;filter {filter} for attributes {attrs}.&quot;,
-                       base=ldap.dn.dn2str(base), filter=filterstr,
-                       attrs=self.attrlist)
</del><ins>+        self.log.debug(
+            &quot;Querying ldap for records matching base {base} and &quot;
+            &quot;filter {filter} for attributes {attrs}.&quot;,
+            base=ldap.dn.dn2str(base), filter=filterstr,
+            attrs=self.attrlist
+        )
</ins><span class="cx"> 
</span><span class="cx">         # This takes a while, so if you don't want to have a &quot;long request&quot;
</span><span class="cx">         # warning logged, use this instead of timedSearch:
</span><span class="cx">         # results = self.ldap.search_s(ldap.dn.dn2str(base),
</span><span class="cx">         #     ldap.SCOPE_SUBTREE, filterstr=filterstr, attrlist=self.attrlist)
</span><del>-        results = self.timedSearch(ldap.dn.dn2str(base), ldap.SCOPE_SUBTREE,
-                                   filterstr=filterstr, attrlist=self.attrlist)
</del><ins>+        results = self.timedSearch(
+            ldap.dn.dn2str(base), ldap.SCOPE_SUBTREE,
+            filterstr=filterstr, attrlist=self.attrlist
+        )
</ins><span class="cx"> 
</span><span class="cx">         records = []
</span><span class="cx">         numMissingGuids = 0
</span><span class="lines">@@ -343,17 +347,19 @@
</span><span class="cx"> 
</span><span class="cx">             if not unrestricted:
</span><span class="cx">                 self.log.debug(
</span><del>-                    &quot;{dn} is not enabled because it's not a member of group: {group}&quot;,
-                    dn=dn, group=self.restrictToGroup)
</del><ins>+                    &quot;{dn} is not enabled because it's not a member of group: &quot;
+                    &quot;{group}&quot;, dn=dn, group=self.restrictToGroup
+                )
</ins><span class="cx">                 record.enabledForCalendaring = False
</span><span class="cx">                 record.enabledForAddressBooks = False
</span><span class="cx"> 
</span><span class="cx">             records.append(record)
</span><span class="cx"> 
</span><span class="cx">         if numMissingGuids:
</span><del>-            self.log.info(&quot;{num} {recordType} records are missing {attr}&quot;,
-                          num=numMissingGuids, recordType=recordType,
-                          attr=guidAttr)
</del><ins>+            self.log.info(
+                &quot;{num} {recordType} records are missing {attr}&quot;,
+                num=numMissingGuids, recordType=recordType, attr=guidAttr
+            )
</ins><span class="cx"> 
</span><span class="cx">         return records
</span><span class="cx"> 
</span><span class="lines">@@ -372,7 +378,9 @@
</span><span class="cx">         attributeToSearch = &quot;memberIdAttr&quot; if memberIdAttr else &quot;dn&quot;
</span><span class="cx"> 
</span><span class="cx">         fields = [[attributeToSearch, alias, False, &quot;equals&quot;]]
</span><del>-        results = (yield self.recordsMatchingFields(fields, recordType=recordType))
</del><ins>+        results = yield self.recordsMatchingFields(
+            fields, recordType=recordType
+        )
</ins><span class="cx">         if results:
</span><span class="cx">             returnValue(results[0])
</span><span class="cx">         else:
</span><span class="lines">@@ -391,9 +399,15 @@
</span><span class="cx">         readAttr = self.resourceSchema[&quot;readOnlyProxyAttr&quot;]
</span><span class="cx">         writeAttr = self.resourceSchema[&quot;proxyAttr&quot;]
</span><span class="cx">         if not (guidAttr and readAttr and writeAttr):
</span><del>-            self.log.error(&quot;LDAP configuration requires guidAttr, proxyAttr, and readOnlyProxyAttr in order to use external proxy assignments efficiently; falling back to slower method&quot;)
</del><ins>+            self.log.error(
+                &quot;LDAP configuration requires guidAttr, proxyAttr, and &quot;
+                &quot;readOnlyProxyAttr in order to use external proxy assignments &quot;
+                &quot;efficiently; falling back to slower method&quot;
+            )
</ins><span class="cx">             # Fall back to the less-specialized version
</span><del>-            return super(LdapDirectoryService, self).getExternalProxyAssignments()
</del><ins>+            return super(
+                LdapDirectoryService, self
+            ).getExternalProxyAssignments()
</ins><span class="cx"> 
</span><span class="cx">         # Build filter
</span><span class="cx">         filterstr = &quot;(|(%s=*)(%s=*))&quot; % (readAttr, writeAttr)
</span><span class="lines">@@ -406,10 +420,12 @@
</span><span class="cx">         attrlist = [guidAttr, readAttr, writeAttr]
</span><span class="cx"> 
</span><span class="cx">         # Query the LDAP server
</span><del>-        self.log.debug(&quot;Querying ldap for records matching base {base} and &quot;
-                       &quot;filter {filter} for attributes {attrs}.&quot;,
-                       base=ldap.dn.dn2str(self.base), filter=filterstr,
-                       attrs=attrlist)
</del><ins>+        self.log.debug(
+            &quot;Querying ldap for records matching base {base} and filter &quot;
+            &quot;{filter} for attributes {attrs}.&quot;,
+            base=ldap.dn.dn2str(self.base), filter=filterstr,
+            attrs=attrlist
+        )
</ins><span class="cx"> 
</span><span class="cx">         results = self.timedSearch(ldap.dn.dn2str(self.base),
</span><span class="cx">                                    ldap.SCOPE_SUBTREE, filterstr=filterstr,
</span><span class="lines">@@ -423,13 +439,15 @@
</span><span class="cx">                 readDelegate = self._getUniqueLdapAttribute(attrs, readAttr)
</span><span class="cx">                 if readDelegate:
</span><span class="cx">                     readDelegate = normalizeUUID(readDelegate)
</span><del>-                    assignments.append((&quot;%s#calendar-proxy-read&quot; % (guid,),
-                                       [readDelegate]))
</del><ins>+                    assignments.append(
+                        (&quot;%s#calendar-proxy-read&quot; % (guid,), [readDelegate])
+                    )
</ins><span class="cx">                 writeDelegate = self._getUniqueLdapAttribute(attrs, writeAttr)
</span><span class="cx">                 if writeDelegate:
</span><span class="cx">                     writeDelegate = normalizeUUID(writeDelegate)
</span><del>-                    assignments.append((&quot;%s#calendar-proxy-write&quot; % (guid,),
-                                       [writeDelegate]))
</del><ins>+                    assignments.append(
+                        (&quot;%s#calendar-proxy-write&quot; % (guid,), [writeDelegate])
+                    )
</ins><span class="cx"> 
</span><span class="cx">         return assignments
</span><span class="cx"> 
</span><span class="lines">@@ -438,18 +456,30 @@
</span><span class="cx">         if self.ldap is None:
</span><span class="cx">             self.log.info(&quot;Connecting to LDAP {uri}&quot;, uri=repr(self.uri))
</span><span class="cx">             self.ldap = self.createLDAPConnection()
</span><del>-            self.log.info(&quot;Connection established to LDAP {uri}&quot;, uri=repr(self.uri))
</del><ins>+            self.log.info(
+                &quot;Connection established to LDAP {uri}&quot;, uri=repr(self.uri)
+            )
</ins><span class="cx">             if self.credentials.get(&quot;dn&quot;, &quot;&quot;):
</span><span class="cx">                 try:
</span><del>-                    self.log.info(&quot;Binding to LDAP {dn}&quot;,
-                                  dn=repr(self.credentials.get(&quot;dn&quot;)))
-                    self.ldap.simple_bind_s(self.credentials.get(&quot;dn&quot;),
-                                            self.credentials.get(&quot;password&quot;))
-                    self.log.info(&quot;Successfully authenticated with LDAP as {dn}&quot;,
-                                  dn=repr(self.credentials.get(&quot;dn&quot;)))
</del><ins>+                    self.log.info(
+                        &quot;Binding to LDAP {dn}&quot;,
+                        dn=repr(self.credentials.get(&quot;dn&quot;))
+                    )
+                    self.ldap.simple_bind_s(
+                        self.credentials.get(&quot;dn&quot;),
+                        self.credentials.get(&quot;password&quot;),
+                    )
+                    self.log.info(
+                        &quot;Successfully authenticated with LDAP as {dn}&quot;,
+                        dn=repr(self.credentials.get(&quot;dn&quot;))
+                    )
</ins><span class="cx">                 except ldap.INVALID_CREDENTIALS:
</span><del>-                    self.log.error(&quot;Can't bind to LDAP {uri}: check credentials&quot;, uri=self.uri)
</del><ins>+                    self.log.error(
+                        &quot;Can't bind to LDAP {uri}: check credentials&quot;,
+                        uri=self.uri
+                    )
</ins><span class="cx">                     raise DirectoryConfigurationError()
</span><ins>+
</ins><span class="cx">         return self.ldap
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -489,7 +519,7 @@
</span><span class="cx">         TRIES = 3
</span><span class="cx"> 
</span><span class="cx">         for _ignore_i in xrange(TRIES):
</span><del>-            self.log.debug(&quot;Authenticating %s&quot; % (dn,))
</del><ins>+            self.log.debug(&quot;Authenticating {dn}&quot;, dn=dn)
</ins><span class="cx"> 
</span><span class="cx">             if self.authLDAP is None:
</span><span class="cx">                 self.log.debug(&quot;Creating authentication connection to LDAP&quot;)
</span><span class="lines">@@ -506,8 +536,10 @@
</span><span class="cx">                 raise ldap.INVALID_CREDENTIALS()
</span><span class="cx"> 
</span><span class="cx">             except ldap.NO_SUCH_OBJECT:
</span><del>-                self.log.error(&quot;LDAP Authentication error for %s: NO_SUCH_OBJECT&quot;
-                               % (dn,))
</del><ins>+                self.log.error(
+                    &quot;LDAP Authentication error for {dn}: NO_SUCH_OBJECT&quot;,
+                    dn=dn
+                )
</ins><span class="cx">                 # fall through to try again; could be transient
</span><span class="cx"> 
</span><span class="cx">             except ldap.INVALID_CREDENTIALS:
</span><span class="lines">@@ -519,68 +551,98 @@
</span><span class="cx">                 # Fall through and retry if TRIES has been reached
</span><span class="cx"> 
</span><span class="cx">             except Exception, e:
</span><del>-                self.log.error(&quot;LDAP authentication failed with %s.&quot; % (e,))
</del><ins>+                self.log.error(
+                    &quot;LDAP authentication failed with {e}.&quot;, e=e
+                )
</ins><span class="cx">                 raise
</span><span class="cx"> 
</span><span class="cx">             finally:
</span><span class="cx">                 totalTime = time.time() - startTime
</span><span class="cx">                 if totalTime &gt; self.warningThresholdSeconds:
</span><del>-                    self.log.error(&quot;LDAP auth exceeded threshold: %.2f seconds for %s&quot; % (totalTime, dn))
</del><ins>+                    self.log.error(
+                        &quot;LDAP auth exceeded threshold: {time!.2f} seconds for &quot;
+                        &quot;{dn}&quot;, time=totalTime, dn=dn
+                    )
</ins><span class="cx"> 
</span><span class="cx">         else:
</span><del>-            self.log.error(&quot;Giving up on LDAP authentication after %d tries.  Responding with 503.&quot; % (TRIES,))
-            raise HTTPError(StatusResponse(responsecode.SERVICE_UNAVAILABLE, &quot;LDAP server unavailable&quot;))
</del><ins>+            self.log.error(
+                &quot;Giving up on LDAP authentication after {count!d} tries.  &quot;
+                &quot;Responding with 503.&quot;, count=TRIES
+            )
+            raise HTTPError(StatusResponse(
+                responsecode.SERVICE_UNAVAILABLE, &quot;LDAP server unavailable&quot;
+            ))
</ins><span class="cx"> 
</span><del>-        self.log.debug(&quot;Authentication succeeded for %s&quot; % (dn,))
</del><ins>+        self.log.debug(&quot;Authentication succeeded for {dn}&quot;, dn=dn)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-    def timedSearch(self, base, scope, filterstr=&quot;(objectClass=*)&quot;,
-                    attrlist=None, timeoutSeconds=-1, resultLimit=0):
</del><ins>+    def timedSearch(
+        self, base, scope, filterstr=&quot;(objectClass=*)&quot;, attrlist=None,
+        timeoutSeconds=-1, resultLimit=0
+    ):
</ins><span class="cx">         &quot;&quot;&quot;
</span><del>-        Execute an LDAP query, retrying up to 3 times in case the LDAP server has
-        gone down and we need to reconnect. If it takes longer than the configured
-        threshold, emit a log error.
-        The number of records requested is controlled by resultLimit (0=no limit).
-        If timeoutSeconds is not -1, the query will abort after the specified number
-        of seconds and the results retrieved so far are returned.
</del><ins>+        Execute an LDAP query, retrying up to 3 times in case the LDAP server
+        has gone down and we need to reconnect. If it takes longer than the
+        configured threshold, emit a log error.
+        The number of records requested is controlled by resultLimit (0=no
+        limit).
+        If timeoutSeconds is not -1, the query will abort after the specified
+        number of seconds and the results retrieved so far are returned.
</ins><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         TRIES = 3
</span><span class="cx"> 
</span><span class="cx">         for i in xrange(TRIES):
</span><span class="cx">             try:
</span><span class="cx">                 s = ldap.async.List(self.getLDAPConnection())
</span><del>-                s.startSearch(base, scope, filterstr, attrList=attrlist,
-                              timeout=timeoutSeconds, sizelimit=resultLimit)
</del><ins>+                s.startSearch(
+                    base, scope, filterstr, attrList=attrlist,
+                    timeout=timeoutSeconds, sizelimit=resultLimit
+                )
</ins><span class="cx">                 startTime = time.time()
</span><span class="cx">                 s.processResults()
</span><span class="cx">             except ldap.NO_SUCH_OBJECT:
</span><span class="cx">                 return []
</span><span class="cx">             except ldap.FILTER_ERROR, e:
</span><del>-                self.log.error(&quot;LDAP filter error: %s %s&quot; % (e, filterstr))
</del><ins>+                self.log.error(
+                    &quot;LDAP filter error: {e} {filter}&quot;, e=e, filter=filterstr
+                )
</ins><span class="cx">                 return []
</span><span class="cx">             except ldap.SIZELIMIT_EXCEEDED, e:
</span><del>-                self.log.debug(&quot;LDAP result limit exceeded: %d&quot; % (resultLimit,))
</del><ins>+                self.log.debug(
+                    &quot;LDAP result limit exceeded: {limit!d}&quot;, limit=resultLimit
+                )
</ins><span class="cx">             except ldap.TIMELIMIT_EXCEEDED, e:
</span><del>-                self.log.warn(&quot;LDAP timeout exceeded: %d seconds&quot; % (timeoutSeconds,))
</del><ins>+                self.log.warn(
+                    &quot;LDAP timeout exceeded: {t!d} seconds&quot;, t=timeoutSeconds
+                )
</ins><span class="cx">             except ldap.SERVER_DOWN:
</span><span class="cx">                 self.ldap = None
</span><del>-                self.log.error(&quot;LDAP server unavailable (tried %d times)&quot; % (i + 1,))
</del><ins>+                self.log.error(
+                    &quot;LDAP server unavailable (tried {count!d} times)&quot;,
+                    count=(i + 1)
+                )
</ins><span class="cx">                 continue
</span><span class="cx"> 
</span><span class="cx">             # change format, ignoring resultsType
</span><del>-            result = [resultItem for _ignore_resultType, resultItem in s.allResults]
</del><ins>+            result = [
+                resultItem for _ignore_resultType, resultItem in s.allResults
+            ]
</ins><span class="cx"> 
</span><span class="cx">             totalTime = time.time() - startTime
</span><span class="cx">             if totalTime &gt; self.warningThresholdSeconds:
</span><span class="cx">                 if filterstr and len(filterstr) &gt; 100:
</span><span class="cx">                     filterstr = &quot;%s...&quot; % (filterstr[:100],)
</span><span class="cx">                 self.log.error(
</span><del>-                    &quot;LDAP query exceeded threshold: %.2f seconds for %s %s %s (#results=%d)&quot; %
-                    (totalTime, base, filterstr, attrlist, len(result))
</del><ins>+                    &quot;LDAP query exceeded threshold: {time!.2f} seconds for &quot;
+                    &quot;{base} {filter} {attrs} (#results={count!d})&quot;,
+                    time=totalTime, base=base, filter=filterstr,
+                    attrs=attrlist, count=len(result),
</ins><span class="cx">                 )
</span><span class="cx">             return result
</span><span class="cx"> 
</span><del>-        raise HTTPError(StatusResponse(responsecode.SERVICE_UNAVAILABLE, &quot;LDAP server unavailable&quot;))
</del><ins>+        raise HTTPError(StatusResponse(
+            responsecode.SERVICE_UNAVAILABLE, &quot;LDAP server unavailable&quot;
+        ))
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def isAllowedByRestrictToGroup(self, dn, attrs):
</span><span class="lines">@@ -598,7 +660,9 @@
</span><span class="cx">         if not self.restrictEnabledRecords:
</span><span class="cx">             return True
</span><span class="cx">         if self.groupSchema[&quot;memberIdAttr&quot;]:
</span><del>-            value = self._getUniqueLdapAttribute(attrs, self.groupSchema[&quot;memberIdAttr&quot;])
</del><ins>+            value = self._getUniqueLdapAttribute(
+                attrs, self.groupSchema[&quot;memberIdAttr&quot;]
+            )
</ins><span class="cx">         else:  # No memberIdAttr implies DN
</span><span class="cx">             value = dn
</span><span class="cx">         return value in self.restrictedPrincipals
</span><span class="lines">@@ -619,12 +683,17 @@
</span><span class="cx">                 base = self.typeDNs[recordType]
</span><span class="cx">                 # TODO: This shouldn't be hardcoded to cn
</span><span class="cx">                 filterstr = &quot;(cn=%s)&quot; % (self.restrictToGroup,)
</span><del>-                self.log.debug(&quot;Retrieving ldap record with base %s and filter %s.&quot; %
-                               (ldap.dn.dn2str(base), filterstr))
-                result = self.timedSearch(ldap.dn.dn2str(base),
-                                          ldap.SCOPE_SUBTREE,
-                                          filterstr=filterstr,
-                                          attrlist=self.attrlist)
</del><ins>+                self.log.debug(
+                    &quot;Retrieving ldap record with base {base} and filter &quot;
+                    &quot;{filter}.&quot;,
+                    base=ldap.dn.dn2str(base), filter=filterstr
+                )
+                result = self.timedSearch(
+                    ldap.dn.dn2str(base),
+                    ldap.SCOPE_SUBTREE,
+                    filterstr=filterstr,
+                    attrlist=self.attrlist
+                )
</ins><span class="cx"> 
</span><span class="cx">                 members = []
</span><span class="cx">                 nestedGroups = []
</span><span class="lines">@@ -637,7 +706,7 @@
</span><span class="cx">                             attrs,
</span><span class="cx">                             self.groupSchema[&quot;membersAttr&quot;]
</span><span class="cx">                         )
</span><del>-                        if not self.groupSchema[&quot;memberIdAttr&quot;]:  # these are DNs
</del><ins>+                        if not self.groupSchema[&quot;memberIdAttr&quot;]:  # DNs
</ins><span class="cx">                             members = [normalizeDNstr(m) for m in members]
</span><span class="cx">                         members = set(members)
</span><span class="cx"> 
</span><span class="lines">@@ -646,8 +715,10 @@
</span><span class="cx">                             attrs,
</span><span class="cx">                             self.groupSchema[&quot;nestedGroupsAttr&quot;]
</span><span class="cx">                         )
</span><del>-                        if not self.groupSchema[&quot;memberIdAttr&quot;]:  # these are DNs
-                            nestedGroups = [normalizeDNstr(g) for g in nestedGroups]
</del><ins>+                        if not self.groupSchema[&quot;memberIdAttr&quot;]:  # DNs
+                            nestedGroups = [
+                                normalizeDNstr(g) for g in nestedGroups
+                            ]
</ins><span class="cx">                         nestedGroups = set(nestedGroups)
</span><span class="cx">                     else:
</span><span class="cx">                         # Since all members are lumped into the same attribute,
</span><span class="lines">@@ -658,8 +729,10 @@
</span><span class="cx">                 self._cachedRestrictedPrincipals = set(
</span><span class="cx">                     self._expandGroupMembership(members, nestedGroups)
</span><span class="cx">                 )
</span><del>-                self.log.info(&quot;Got %d restricted group members&quot; % (
-                    len(self._cachedRestrictedPrincipals),))
</del><ins>+                self.log.info(
+                    &quot;Got {count} restricted group members&quot;,
+                    count=len(self._cachedRestrictedPrincipals)
+                )
</ins><span class="cx">                 self.restrictedTimestamp = time.time()
</span><span class="cx">             return self._cachedRestrictedPrincipals
</span><span class="cx">         else:
</span><span class="lines">@@ -717,8 +790,10 @@
</span><span class="cx">                 base = ldap.dn.str2dn(group)
</span><span class="cx">                 filterstr = &quot;(objectClass=*)&quot;
</span><span class="cx"> 
</span><del>-            self.log.debug(&quot;Retrieving ldap record with base %s and filter %s.&quot; %
-                           (ldap.dn.dn2str(base), filterstr))
</del><ins>+            self.log.debug(
+                &quot;Retrieving ldap record with base {base} and filter {filter}.&quot;,
+                base=ldap.dn.dn2str(base), filter=filterstr
+            )
</ins><span class="cx">             result = self.timedSearch(ldap.dn.dn2str(base),
</span><span class="cx">                                       scope,
</span><span class="cx">                                       filterstr=filterstr,
</span><span class="lines">@@ -814,7 +889,11 @@
</span><span class="cx">         if guidAttr:
</span><span class="cx">             guid = self._getUniqueLdapAttribute(attrs, guidAttr)
</span><span class="cx">             if not guid:
</span><del>-                self.log.debug(&quot;LDAP data for %s is missing guid attribute %s&quot; % (shortNames, guidAttr))
</del><ins>+                self.log.debug(
+                    &quot;LDAP data for {shortNames} is missing guid attribute &quot;
+                    &quot;{attr}&quot;,
+                    shortNames=shortNames, attr=guidAttr
+                )
</ins><span class="cx">                 raise MissingGuidException()
</span><span class="cx">             guid = normalizeUUID(guid)
</span><span class="cx"> 
</span><span class="lines">@@ -872,7 +951,7 @@
</span><span class="cx">                         memberGUIDs.append(dnStr)
</span><span class="cx">                     except Exception, e:
</span><span class="cx">                         # LDAP returned an illegal DN value, log and ignore it
</span><del>-                        self.log.warn(&quot;Bad LDAP DN: %s&quot; % (dnStr,))
</del><ins>+                        self.log.warn(&quot;Bad LDAP DN: {dn!r}&quot;, dn=dnStr)
</ins><span class="cx"> 
</span><span class="cx">         elif recordType in (self.recordType_resources,
</span><span class="cx">                             self.recordType_locations):
</span><span class="lines">@@ -903,7 +982,9 @@
</span><span class="cx">                         if readOnlyProxy:
</span><span class="cx">                             readOnlyProxyGUIDs = (readOnlyProxy,)
</span><span class="cx">                     except ValueError, e:
</span><del>-                        self.log.error(&quot;Unable to parse resource info (%s)&quot; % (e,))
</del><ins>+                        self.log.error(
+                            &quot;Unable to parse resource info: {e}&quot;, e=e
+                        )
</ins><span class="cx">             else:  # the individual resource attributes might be specified
</span><span class="cx">                 if self.resourceSchema[&quot;autoScheduleAttr&quot;]:
</span><span class="cx">                     autoScheduleValue = self._getUniqueLdapAttribute(
</span><span class="lines">@@ -1027,7 +1108,9 @@
</span><span class="cx">         return record
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-    def queryDirectory(self, recordTypes, indexType, indexKey, queryMethod=None):
</del><ins>+    def queryDirectory(
+        self, recordTypes, indexType, indexKey, queryMethod=None
+    ):
</ins><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Queries the LDAP directory for the record which has an attribute value
</span><span class="cx">         matching the indexType and indexKey parameters.
</span><span class="lines">@@ -1044,8 +1127,11 @@
</span><span class="cx">         if queryMethod is None:
</span><span class="cx">             queryMethod = self.timedSearch
</span><span class="cx"> 
</span><del>-        self.log.debug(&quot;LDAP query for types %s, indexType %s and indexKey %s&quot;
-                       % (recordTypes, indexType, indexKey))
</del><ins>+        self.log.debug(
+            &quot;LDAP query for types {types}, indexType {indexType} and &quot;
+            &quot;indexKey {indexKey}&quot;,
+            types=recordTypes, indexType=indexType, indexKey=indexKey
+        )
</ins><span class="cx"> 
</span><span class="cx">         guidAttr = self.rdnSchema[&quot;guidAttr&quot;]
</span><span class="cx">         for recordType in recordTypes:
</span><span class="lines">@@ -1076,8 +1162,13 @@
</span><span class="cx">             elif indexType == self.INDEX_TYPE_CUA:
</span><span class="cx">                 # indexKey is of the form &quot;mailto:test@example.net&quot;
</span><span class="cx">                 email = indexKey[7:]  # strip &quot;mailto:&quot;
</span><del>-                emailSuffix = self.rdnSchema[recordType].get(&quot;emailSuffix&quot;, None)
-                if emailSuffix is not None and email.partition(&quot;@&quot;)[2] == emailSuffix:
</del><ins>+                emailSuffix = self.rdnSchema[recordType].get(
+                    &quot;emailSuffix&quot;, None
+                )
+                if (
+                    emailSuffix is not None and
+                    email.partition(&quot;@&quot;)[2] == emailSuffix
+                ):
</ins><span class="cx">                     filterstr = &quot;(&amp;%s(|(&amp;(!(mail=*))(%s=%s))(mail=%s)))&quot; % (
</span><span class="cx">                         filterstr,
</span><span class="cx">                         self.rdnSchema[recordType].get(&quot;attr&quot;, &quot;cn&quot;),
</span><span class="lines">@@ -1086,20 +1177,28 @@
</span><span class="cx">                     )
</span><span class="cx">                 else:
</span><span class="cx">                     # emailAddresses can map to multiple LDAP fields
</span><del>-                    ldapFields = self.rdnSchema[recordType][&quot;mapping&quot;].get(&quot;emailAddresses&quot;, &quot;&quot;)
</del><ins>+                    ldapFields = self.rdnSchema[recordType][&quot;mapping&quot;].get(
+                        &quot;emailAddresses&quot;, &quot;&quot;
+                    )
</ins><span class="cx">                     if isinstance(ldapFields, str):
</span><span class="cx">                         if ldapFields:
</span><del>-                            subfilter = &quot;(%s=%s)&quot; % (ldapFields, ldapEsc(email))
</del><ins>+                            subfilter = (
+                                &quot;(%s=%s)&quot; % (ldapFields, ldapEsc(email))
+                            )
</ins><span class="cx">                         else:
</span><del>-                            continue  # No LDAP attribute assigned for emailAddresses
</del><ins>+                            # No LDAP attribute assigned for emailAddresses
+                            continue
</ins><span class="cx"> 
</span><span class="cx">                     else:
</span><span class="cx">                         subfilter = []
</span><span class="cx">                         for ldapField in ldapFields:
</span><span class="cx">                             if ldapField:
</span><del>-                                subfilter.append(&quot;(%s=%s)&quot; % (ldapField, ldapEsc(email)))
</del><ins>+                                subfilter.append(
+                                    &quot;(%s=%s)&quot; % (ldapField, ldapEsc(email))
+                                )
</ins><span class="cx">                         if not subfilter:
</span><del>-                            continue  # No LDAP attribute assigned for emailAddresses
</del><ins>+                            # No LDAP attribute assigned for emailAddresses
+                            continue
</ins><span class="cx"> 
</span><span class="cx">                         subfilter = &quot;(|%s)&quot; % (&quot;&quot;.join(subfilter))
</span><span class="cx">                     filterstr = &quot;(&amp;%s%s)&quot; % (filterstr, subfilter)
</span><span class="lines">@@ -1108,12 +1207,16 @@
</span><span class="cx">                 return
</span><span class="cx"> 
</span><span class="cx">             # Query the LDAP server
</span><del>-            self.log.debug(&quot;Retrieving ldap record with base %s and filter %s.&quot; %
-                           (ldap.dn.dn2str(base), filterstr))
-            result = queryMethod(ldap.dn.dn2str(base),
-                                 ldap.SCOPE_SUBTREE,
-                                 filterstr=filterstr,
-                                 attrlist=self.attrlist)
</del><ins>+            self.log.debug(
+                &quot;Retrieving ldap record with base %s and filter %s.&quot;,
+                base=ldap.dn.dn2str(base), filter=filterstr,
+            )
+            result = queryMethod(
+                ldap.dn.dn2str(base),
+                ldap.SCOPE_SUBTREE,
+                filterstr=filterstr,
+                attrlist=self.attrlist,
+            )
</ins><span class="cx"> 
</span><span class="cx">             if result:
</span><span class="cx">                 dn, attrs = result.pop()
</span><span class="lines">@@ -1126,7 +1229,11 @@
</span><span class="cx">                     self.log.debug(&quot;Got LDAP record {rec}&quot;, rec=record)
</span><span class="cx"> 
</span><span class="cx">                     if not unrestricted:
</span><del>-                        self.log.debug(&quot;%s is not enabled because it's not a member of group: %s&quot; % (dn, self.restrictToGroup))
</del><ins>+                        self.log.debug(
+                            &quot;{dn} is not enabled because it's not a member of &quot;
+                            &quot;group {group!r}&quot;,
+                            dn=dn, group=self.restrictToGroup
+                        )
</ins><span class="cx">                         record.enabledForCalendaring = False
</span><span class="cx">                         record.enabledForAddressBooks = False
</span><span class="cx"> 
</span><span class="lines">@@ -1142,15 +1249,19 @@
</span><span class="cx">                 except MissingRecordNameException:
</span><span class="cx">                     self.log.warn(
</span><span class="cx">                         &quot;Ignoring record missing record name &quot;
</span><del>-                        &quot;attribute: recordType %s, indexType %s and indexKey %s&quot;
-                        % (recordTypes, indexType, indexKey)
</del><ins>+                        &quot;attribute: recordType {recordType}, indexType &quot;
+                        &quot;{indexType} and indexKey {indexKey}&quot;,
+                        recordTypes=recordTypes, indexType=indexType,
+                        indexKey=indexKey,
</ins><span class="cx">                     )
</span><span class="cx"> 
</span><span class="cx">                 except MissingGuidException:
</span><span class="cx">                     self.log.warn(
</span><span class="cx">                         &quot;Ignoring record missing guid attribute: &quot;
</span><del>-                        &quot;recordType %s, indexType %s and indexKey %s&quot;
-                        % (recordTypes, indexType, indexKey)
</del><ins>+                        &quot;recordType {recordType}, indexType {indexType} and &quot;
+                        &quot;indexKey {indexKey}&quot;,
+                        recordTypes=recordTypes, indexType=indexType,
+                        indexKey=indexKey
</ins><span class="cx">                     )
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1175,7 +1286,10 @@
</span><span class="cx">         context is &quot;attendee&quot;, only users, groups, and resources
</span><span class="cx">         are considered.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        self.log.debug(&quot;Peforming calendar user search for %s (%s)&quot; % (tokens, context))
</del><ins>+        self.log.debug(
+            &quot;Peforming calendar user search for {tokens} ({context})&quot;,
+            tokens=tokens, context=context
+        )
</ins><span class="cx">         startTime = time.time()
</span><span class="cx">         records = []
</span><span class="cx">         recordTypes = self.recordTypesForSearchContext(context)
</span><span class="lines">@@ -1200,8 +1314,9 @@
</span><span class="cx">             if filterstr is not None:
</span><span class="cx">                 # Query the LDAP server
</span><span class="cx">                 self.log.debug(
</span><del>-                    &quot;LDAP search %s %s (limit=%d)&quot; %
-                    (ldap.dn.dn2str(base), filterstr, limitResults)
</del><ins>+                    &quot;LDAP search {base} {filter} (limit={limit!d})&quot;,
+                    base=ldap.dn.dn2str(base), filter=filterstr,
+                    limit=limitResults,
</ins><span class="cx">                 )
</span><span class="cx">                 results = self.timedSearch(
</span><span class="cx">                     ldap.dn.dn2str(base),
</span><span class="lines">@@ -1244,11 +1359,22 @@
</span><span class="cx">                     except MissingRecordNameException:
</span><span class="cx">                         numMissingRecordNames += 1
</span><span class="cx"> 
</span><del>-                self.log.debug(&quot;LDAP search returned %d results, %d usable&quot; % (len(results), typeCounts[recordType]))
</del><ins>+                self.log.debug(
+                    &quot;LDAP search returned {resultCount!d} results, &quot;
+                    &quot;{typeCount!d} usable&quot;,
+                    resultCount=len(results), typeCount=typeCounts[recordType]
+                )
</ins><span class="cx"> 
</span><del>-        typeCountsStr = &quot;, &quot;.join([&quot;%s:%d&quot; % (rt, ct) for (rt, ct) in typeCounts.iteritems()])
</del><ins>+        typeCountsStr = &quot;, &quot;.join(
+            [&quot;%s:%d&quot; % (rt, ct) for (rt, ct) in typeCounts.iteritems()]
+        )
</ins><span class="cx">         totalTime = time.time() - startTime
</span><del>-        self.log.info(&quot;Calendar user search for %s matched %d records (%s) in %.2f seconds&quot; % (tokens, len(records), typeCountsStr, totalTime))
</del><ins>+        self.log.info(
+            &quot;Calendar user search for {tokens} matched {recordCount!d} &quot;
+            &quot;records ({typeCount}) in {time!.2f} seconds&quot;,
+            tokens=tokens, recordCount=len(records),
+            typeCount=typeCountsStr, time=totalTime,
+        )
</ins><span class="cx">         return succeed(records)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1260,7 +1386,9 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         records = []
</span><span class="cx"> 
</span><del>-        self.log.debug(&quot;Performing principal property search for %s&quot; % (fields,))
</del><ins>+        self.log.debug(
+            &quot;Performing principal property search for {fields}&quot;, fields=fields
+        )
</ins><span class="cx"> 
</span><span class="cx">         if recordType is None:
</span><span class="cx">             # Make a copy since we're modifying it
</span><span class="lines">@@ -1300,8 +1428,10 @@
</span><span class="cx"> 
</span><span class="cx">             if filterstr is not None:
</span><span class="cx">                 # Query the LDAP server
</span><del>-                self.log.debug(&quot;LDAP search %s %s %s&quot; %
-                               (ldap.dn.dn2str(base), scope, filterstr))
</del><ins>+                self.log.debug(
+                    &quot;LDAP search {base} {scope} {filter}&quot;,
+                    base=ldap.dn.dn2str(base), scope=scope, filter=filterstr
+                )
</ins><span class="cx">                 results = (yield deferToThread(
</span><span class="cx">                     self.timedSearch,
</span><span class="cx">                     ldap.dn.dn2str(base),
</span><span class="lines">@@ -1311,7 +1441,9 @@
</span><span class="cx">                     timeoutSeconds=self.requestTimeoutSeconds,
</span><span class="cx">                     resultLimit=self.requestResultsLimit)
</span><span class="cx">                 )
</span><del>-                self.log.debug(&quot;LDAP search returned %d results&quot; % (len(results),))
</del><ins>+                self.log.debug(
+                    &quot;LDAP search returned {count} results&quot;, count=len(results)
+                )
</ins><span class="cx">                 numMissingGuids = 0
</span><span class="cx">                 numMissingRecordNames = 0
</span><span class="cx">                 for dn, attrs in results:
</span><span class="lines">@@ -1342,14 +1474,21 @@
</span><span class="cx">                         numMissingRecordNames += 1
</span><span class="cx"> 
</span><span class="cx">                 if numMissingGuids:
</span><del>-                    self.log.warn(&quot;%d %s records are missing %s&quot; %
-                                  (numMissingGuids, recordType, guidAttr))
</del><ins>+                    self.log.warn(
+                        &quot;{count!d} {type} records are missing {attr}&quot;,
+                        count=numMissingGuids, type=recordType, attr=guidAttr
+                    )
</ins><span class="cx"> 
</span><span class="cx">                 if numMissingRecordNames:
</span><del>-                    self.log.warn(&quot;%d %s records are missing record name&quot; %
-                                  (numMissingRecordNames, recordType))
</del><ins>+                    self.log.warn(
+                        &quot;{count!d} {type} records are missing record name&quot;,
+                        count=numMissingRecordNames, type=recordType,
+                    )
</ins><span class="cx"> 
</span><del>-        self.log.debug(&quot;Principal property search matched %d records&quot; % (len(records),))
</del><ins>+        self.log.debug(
+            &quot;Principal property search matched {count} records&quot;,
+            count=len(records)
+        )
</ins><span class="cx">         returnValue(records)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1695,9 +1834,11 @@
</span><span class="cx"> 
</span><span class="cx">                 base = self.service.base
</span><span class="cx">                 filterstr = &quot;(%s=%s)&quot; % (memberIdAttr, ldapEsc(memberId))
</span><del>-                self.log.debug(&quot;Retrieving subtree of %s with filter %s&quot; %
-                               (ldap.dn.dn2str(base), filterstr),
-                               system=&quot;LdapDirectoryService&quot;)
</del><ins>+                self.log.debug(
+                    &quot;Retrieving subtree of {base} with filter {filter}&quot;,
+                    base=ldap.dn.dn2str(base), filter=filterstr,
+                    system=&quot;LdapDirectoryService&quot;
+                )
</ins><span class="cx">                 result = self.service.timedSearch(
</span><span class="cx">                     ldap.dn.dn2str(base),
</span><span class="cx">                     ldap.SCOPE_SUBTREE,
</span><span class="lines">@@ -1707,8 +1848,10 @@
</span><span class="cx"> 
</span><span class="cx">             else:  # using DN
</span><span class="cx"> 
</span><del>-                self.log.debug(&quot;Retrieving %s.&quot; % memberId,
-                               system=&quot;LdapDirectoryService&quot;)
</del><ins>+                self.log.debug(
+                    &quot;Retrieving {id}.&quot;,
+                    id=memberId, system=&quot;LdapDirectoryService&quot;
+                )
</ins><span class="cx">                 result = self.service.timedSearch(
</span><span class="cx">                     memberId,
</span><span class="cx">                     ldap.SCOPE_BASE, attrlist=self.service.attrlist
</span><span class="lines">@@ -1718,10 +1861,12 @@
</span><span class="cx"> 
</span><span class="cx">                 dn, attrs = result.pop()
</span><span class="cx">                 dn = normalizeDNstr(dn)
</span><del>-                self.log.debug(&quot;Retrieved: %s %s&quot; % (dn, attrs))
</del><ins>+                self.log.debug(&quot;Retrieved: {dn} {attrs}&quot;, dn=dn, attrs=attrs)
</ins><span class="cx">                 recordType = self.service.recordTypeForDN(dn)
</span><span class="cx">                 if recordType is None:
</span><del>-                    self.log.error(&quot;Unable to map %s to a record type&quot; % (dn,))
</del><ins>+                    self.log.error(
+                        &quot;Unable to map {dn} to a record type&quot;, dn=dn
+                    )
</ins><span class="cx">                     continue
</span><span class="cx"> 
</span><span class="cx">                 shortName = self.service._getUniqueLdapAttribute(
</span><span class="lines">@@ -1769,7 +1914,7 @@
</span><span class="cx">                     [&quot;(%s=%s)&quot; % (a, self._memberId) for a in membersAttrs]
</span><span class="cx">                 ),
</span><span class="cx">             )
</span><del>-        self.log.debug(&quot;Finding groups containing %s&quot; % (self._memberId,))
</del><ins>+        self.log.debug(&quot;Finding groups containing {id}&quot;, id=self._memberId)
</ins><span class="cx">         groups = []
</span><span class="cx"> 
</span><span class="cx">         try:
</span><span class="lines">@@ -1783,12 +1928,15 @@
</span><span class="cx">             for dn, attrs in results:
</span><span class="cx">                 dn = normalizeDNstr(dn)
</span><span class="cx">                 shortName = self.service._getUniqueLdapAttribute(attrs, &quot;cn&quot;)
</span><del>-                self.log.debug(&quot;%s is a member of %s&quot; % (self._memberId, shortName))
</del><ins>+                self.log.debug(
+                    &quot;{id} is a member of {shortName}&quot;,
+                    id=self._memberId, shortName=shortName
+                )
</ins><span class="cx">                 record = self.service.recordWithShortName(recordType, shortName)
</span><span class="cx">                 if record is not None:
</span><span class="cx">                     groups.append(record)
</span><span class="cx">         except ldap.PROTOCOL_ERROR, e:
</span><del>-            self.log.warn(str(e))
</del><ins>+            self.log.warn(&quot;{e}&quot;, e=e)
</ins><span class="cx"> 
</span><span class="cx">         return groups
</span><span class="cx"> 
</span><span class="lines">@@ -1858,14 +2006,17 @@
</span><span class="cx">                     return True
</span><span class="cx"> 
</span><span class="cx">                 except ldap.INVALID_CREDENTIALS:
</span><del>-                    self.log.info(&quot;Invalid credentials for {dn}&quot;,
-                                  dn=repr(self.dn),
-                                  system=&quot;LdapDirectoryService&quot;)
</del><ins>+                    self.log.info(
+                        &quot;Invalid credentials for {dn}&quot;,
+                        dn=repr(self.dn), system=&quot;LdapDirectoryService&quot;
+                    )
</ins><span class="cx">                     return False
</span><span class="cx"> 
</span><span class="cx">             else:
</span><del>-                self.log.error(&quot;Unknown Authentication Method '{method}'&quot;,
-                               method=self.service.authMethod.upper())
</del><ins>+                self.log.error(
+                    &quot;Unknown Authentication Method {method!r}&quot;,
+                    method=self.service.authMethod.upper()
+                )
</ins><span class="cx">                 raise DirectoryConfigurationError()
</span><span class="cx"> 
</span><span class="cx">         return super(LdapDirectoryRecord, self).verifyCredentials(credentials)
</span></span></pre>
</div>
</div>

</body>
</html>