<!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 = "(&%s%s)" % (filterstr, typeFilter)
</span><span class="cx">
</span><span class="cx"> # Query the LDAP server
</span><del>- self.log.debug("Querying ldap for records matching base {base} and "
- "filter {filter} for attributes {attrs}.",
- base=ldap.dn.dn2str(base), filter=filterstr,
- attrs=self.attrlist)
</del><ins>+ self.log.debug(
+ "Querying ldap for records matching base {base} and "
+ "filter {filter} for attributes {attrs}.",
+ 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 "long request"
</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>- "{dn} is not enabled because it's not a member of group: {group}",
- dn=dn, group=self.restrictToGroup)
</del><ins>+ "{dn} is not enabled because it's not a member of group: "
+ "{group}", 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("{num} {recordType} records are missing {attr}",
- num=numMissingGuids, recordType=recordType,
- attr=guidAttr)
</del><ins>+ self.log.info(
+ "{num} {recordType} records are missing {attr}",
+ 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 = "memberIdAttr" if memberIdAttr else "dn"
</span><span class="cx">
</span><span class="cx"> fields = [[attributeToSearch, alias, False, "equals"]]
</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["readOnlyProxyAttr"]
</span><span class="cx"> writeAttr = self.resourceSchema["proxyAttr"]
</span><span class="cx"> if not (guidAttr and readAttr and writeAttr):
</span><del>- self.log.error("LDAP configuration requires guidAttr, proxyAttr, and readOnlyProxyAttr in order to use external proxy assignments efficiently; falling back to slower method")
</del><ins>+ self.log.error(
+ "LDAP configuration requires guidAttr, proxyAttr, and "
+ "readOnlyProxyAttr in order to use external proxy assignments "
+ "efficiently; falling back to slower method"
+ )
</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 = "(|(%s=*)(%s=*))" % (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("Querying ldap for records matching base {base} and "
- "filter {filter} for attributes {attrs}.",
- base=ldap.dn.dn2str(self.base), filter=filterstr,
- attrs=attrlist)
</del><ins>+ self.log.debug(
+ "Querying ldap for records matching base {base} and filter "
+ "{filter} for attributes {attrs}.",
+ 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(("%s#calendar-proxy-read" % (guid,),
- [readDelegate]))
</del><ins>+ assignments.append(
+ ("%s#calendar-proxy-read" % (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(("%s#calendar-proxy-write" % (guid,),
- [writeDelegate]))
</del><ins>+ assignments.append(
+ ("%s#calendar-proxy-write" % (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("Connecting to LDAP {uri}", uri=repr(self.uri))
</span><span class="cx"> self.ldap = self.createLDAPConnection()
</span><del>- self.log.info("Connection established to LDAP {uri}", uri=repr(self.uri))
</del><ins>+ self.log.info(
+ "Connection established to LDAP {uri}", uri=repr(self.uri)
+ )
</ins><span class="cx"> if self.credentials.get("dn", ""):
</span><span class="cx"> try:
</span><del>- self.log.info("Binding to LDAP {dn}",
- dn=repr(self.credentials.get("dn")))
- self.ldap.simple_bind_s(self.credentials.get("dn"),
- self.credentials.get("password"))
- self.log.info("Successfully authenticated with LDAP as {dn}",
- dn=repr(self.credentials.get("dn")))
</del><ins>+ self.log.info(
+ "Binding to LDAP {dn}",
+ dn=repr(self.credentials.get("dn"))
+ )
+ self.ldap.simple_bind_s(
+ self.credentials.get("dn"),
+ self.credentials.get("password"),
+ )
+ self.log.info(
+ "Successfully authenticated with LDAP as {dn}",
+ dn=repr(self.credentials.get("dn"))
+ )
</ins><span class="cx"> except ldap.INVALID_CREDENTIALS:
</span><del>- self.log.error("Can't bind to LDAP {uri}: check credentials", uri=self.uri)
</del><ins>+ self.log.error(
+ "Can't bind to LDAP {uri}: check credentials",
+ 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("Authenticating %s" % (dn,))
</del><ins>+ self.log.debug("Authenticating {dn}", dn=dn)
</ins><span class="cx">
</span><span class="cx"> if self.authLDAP is None:
</span><span class="cx"> self.log.debug("Creating authentication connection to LDAP")
</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("LDAP Authentication error for %s: NO_SUCH_OBJECT"
- % (dn,))
</del><ins>+ self.log.error(
+ "LDAP Authentication error for {dn}: NO_SUCH_OBJECT",
+ 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("LDAP authentication failed with %s." % (e,))
</del><ins>+ self.log.error(
+ "LDAP authentication failed with {e}.", 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 > self.warningThresholdSeconds:
</span><del>- self.log.error("LDAP auth exceeded threshold: %.2f seconds for %s" % (totalTime, dn))
</del><ins>+ self.log.error(
+ "LDAP auth exceeded threshold: {time!.2f} seconds for "
+ "{dn}", time=totalTime, dn=dn
+ )
</ins><span class="cx">
</span><span class="cx"> else:
</span><del>- self.log.error("Giving up on LDAP authentication after %d tries. Responding with 503." % (TRIES,))
- raise HTTPError(StatusResponse(responsecode.SERVICE_UNAVAILABLE, "LDAP server unavailable"))
</del><ins>+ self.log.error(
+ "Giving up on LDAP authentication after {count!d} tries. "
+ "Responding with 503.", count=TRIES
+ )
+ raise HTTPError(StatusResponse(
+ responsecode.SERVICE_UNAVAILABLE, "LDAP server unavailable"
+ ))
</ins><span class="cx">
</span><del>- self.log.debug("Authentication succeeded for %s" % (dn,))
</del><ins>+ self.log.debug("Authentication succeeded for {dn}", dn=dn)
</ins><span class="cx">
</span><span class="cx">
</span><del>- def timedSearch(self, base, scope, filterstr="(objectClass=*)",
- attrlist=None, timeoutSeconds=-1, resultLimit=0):
</del><ins>+ def timedSearch(
+ self, base, scope, filterstr="(objectClass=*)", attrlist=None,
+ timeoutSeconds=-1, resultLimit=0
+ ):
</ins><span class="cx"> """
</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"> """
</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("LDAP filter error: %s %s" % (e, filterstr))
</del><ins>+ self.log.error(
+ "LDAP filter error: {e} {filter}", e=e, filter=filterstr
+ )
</ins><span class="cx"> return []
</span><span class="cx"> except ldap.SIZELIMIT_EXCEEDED, e:
</span><del>- self.log.debug("LDAP result limit exceeded: %d" % (resultLimit,))
</del><ins>+ self.log.debug(
+ "LDAP result limit exceeded: {limit!d}", limit=resultLimit
+ )
</ins><span class="cx"> except ldap.TIMELIMIT_EXCEEDED, e:
</span><del>- self.log.warn("LDAP timeout exceeded: %d seconds" % (timeoutSeconds,))
</del><ins>+ self.log.warn(
+ "LDAP timeout exceeded: {t!d} seconds", t=timeoutSeconds
+ )
</ins><span class="cx"> except ldap.SERVER_DOWN:
</span><span class="cx"> self.ldap = None
</span><del>- self.log.error("LDAP server unavailable (tried %d times)" % (i + 1,))
</del><ins>+ self.log.error(
+ "LDAP server unavailable (tried {count!d} times)",
+ 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 > self.warningThresholdSeconds:
</span><span class="cx"> if filterstr and len(filterstr) > 100:
</span><span class="cx"> filterstr = "%s..." % (filterstr[:100],)
</span><span class="cx"> self.log.error(
</span><del>- "LDAP query exceeded threshold: %.2f seconds for %s %s %s (#results=%d)" %
- (totalTime, base, filterstr, attrlist, len(result))
</del><ins>+ "LDAP query exceeded threshold: {time!.2f} seconds for "
+ "{base} {filter} {attrs} (#results={count!d})",
+ 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, "LDAP server unavailable"))
</del><ins>+ raise HTTPError(StatusResponse(
+ responsecode.SERVICE_UNAVAILABLE, "LDAP server unavailable"
+ ))
</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["memberIdAttr"]:
</span><del>- value = self._getUniqueLdapAttribute(attrs, self.groupSchema["memberIdAttr"])
</del><ins>+ value = self._getUniqueLdapAttribute(
+ attrs, self.groupSchema["memberIdAttr"]
+ )
</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 = "(cn=%s)" % (self.restrictToGroup,)
</span><del>- self.log.debug("Retrieving ldap record with base %s and filter %s." %
- (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(
+ "Retrieving ldap record with base {base} and filter "
+ "{filter}.",
+ 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["membersAttr"]
</span><span class="cx"> )
</span><del>- if not self.groupSchema["memberIdAttr"]: # these are DNs
</del><ins>+ if not self.groupSchema["memberIdAttr"]: # 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["nestedGroupsAttr"]
</span><span class="cx"> )
</span><del>- if not self.groupSchema["memberIdAttr"]: # these are DNs
- nestedGroups = [normalizeDNstr(g) for g in nestedGroups]
</del><ins>+ if not self.groupSchema["memberIdAttr"]: # 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("Got %d restricted group members" % (
- len(self._cachedRestrictedPrincipals),))
</del><ins>+ self.log.info(
+ "Got {count} restricted group members",
+ 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 = "(objectClass=*)"
</span><span class="cx">
</span><del>- self.log.debug("Retrieving ldap record with base %s and filter %s." %
- (ldap.dn.dn2str(base), filterstr))
</del><ins>+ self.log.debug(
+ "Retrieving ldap record with base {base} and filter {filter}.",
+ 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("LDAP data for %s is missing guid attribute %s" % (shortNames, guidAttr))
</del><ins>+ self.log.debug(
+ "LDAP data for {shortNames} is missing guid attribute "
+ "{attr}",
+ 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("Bad LDAP DN: %s" % (dnStr,))
</del><ins>+ self.log.warn("Bad LDAP DN: {dn!r}", 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("Unable to parse resource info (%s)" % (e,))
</del><ins>+ self.log.error(
+ "Unable to parse resource info: {e}", e=e
+ )
</ins><span class="cx"> else: # the individual resource attributes might be specified
</span><span class="cx"> if self.resourceSchema["autoScheduleAttr"]:
</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"> """
</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("LDAP query for types %s, indexType %s and indexKey %s"
- % (recordTypes, indexType, indexKey))
</del><ins>+ self.log.debug(
+ "LDAP query for types {types}, indexType {indexType} and "
+ "indexKey {indexKey}",
+ types=recordTypes, indexType=indexType, indexKey=indexKey
+ )
</ins><span class="cx">
</span><span class="cx"> guidAttr = self.rdnSchema["guidAttr"]
</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 "mailto:test@example.net"
</span><span class="cx"> email = indexKey[7:] # strip "mailto:"
</span><del>- emailSuffix = self.rdnSchema[recordType].get("emailSuffix", None)
- if emailSuffix is not None and email.partition("@")[2] == emailSuffix:
</del><ins>+ emailSuffix = self.rdnSchema[recordType].get(
+ "emailSuffix", None
+ )
+ if (
+ emailSuffix is not None and
+ email.partition("@")[2] == emailSuffix
+ ):
</ins><span class="cx"> filterstr = "(&%s(|(&(!(mail=*))(%s=%s))(mail=%s)))" % (
</span><span class="cx"> filterstr,
</span><span class="cx"> self.rdnSchema[recordType].get("attr", "cn"),
</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]["mapping"].get("emailAddresses", "")
</del><ins>+ ldapFields = self.rdnSchema[recordType]["mapping"].get(
+ "emailAddresses", ""
+ )
</ins><span class="cx"> if isinstance(ldapFields, str):
</span><span class="cx"> if ldapFields:
</span><del>- subfilter = "(%s=%s)" % (ldapFields, ldapEsc(email))
</del><ins>+ subfilter = (
+ "(%s=%s)" % (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("(%s=%s)" % (ldapField, ldapEsc(email)))
</del><ins>+ subfilter.append(
+ "(%s=%s)" % (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 = "(|%s)" % ("".join(subfilter))
</span><span class="cx"> filterstr = "(&%s%s)" % (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("Retrieving ldap record with base %s and filter %s." %
- (ldap.dn.dn2str(base), filterstr))
- result = queryMethod(ldap.dn.dn2str(base),
- ldap.SCOPE_SUBTREE,
- filterstr=filterstr,
- attrlist=self.attrlist)
</del><ins>+ self.log.debug(
+ "Retrieving ldap record with base %s and filter %s.",
+ 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("Got LDAP record {rec}", rec=record)
</span><span class="cx">
</span><span class="cx"> if not unrestricted:
</span><del>- self.log.debug("%s is not enabled because it's not a member of group: %s" % (dn, self.restrictToGroup))
</del><ins>+ self.log.debug(
+ "{dn} is not enabled because it's not a member of "
+ "group {group!r}",
+ 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"> "Ignoring record missing record name "
</span><del>- "attribute: recordType %s, indexType %s and indexKey %s"
- % (recordTypes, indexType, indexKey)
</del><ins>+ "attribute: recordType {recordType}, indexType "
+ "{indexType} and indexKey {indexKey}",
+ 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"> "Ignoring record missing guid attribute: "
</span><del>- "recordType %s, indexType %s and indexKey %s"
- % (recordTypes, indexType, indexKey)
</del><ins>+ "recordType {recordType}, indexType {indexType} and "
+ "indexKey {indexKey}",
+ 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 "attendee", only users, groups, and resources
</span><span class="cx"> are considered.
</span><span class="cx"> """
</span><del>- self.log.debug("Peforming calendar user search for %s (%s)" % (tokens, context))
</del><ins>+ self.log.debug(
+ "Peforming calendar user search for {tokens} ({context})",
+ 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>- "LDAP search %s %s (limit=%d)" %
- (ldap.dn.dn2str(base), filterstr, limitResults)
</del><ins>+ "LDAP search {base} {filter} (limit={limit!d})",
+ 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("LDAP search returned %d results, %d usable" % (len(results), typeCounts[recordType]))
</del><ins>+ self.log.debug(
+ "LDAP search returned {resultCount!d} results, "
+ "{typeCount!d} usable",
+ resultCount=len(results), typeCount=typeCounts[recordType]
+ )
</ins><span class="cx">
</span><del>- typeCountsStr = ", ".join(["%s:%d" % (rt, ct) for (rt, ct) in typeCounts.iteritems()])
</del><ins>+ typeCountsStr = ", ".join(
+ ["%s:%d" % (rt, ct) for (rt, ct) in typeCounts.iteritems()]
+ )
</ins><span class="cx"> totalTime = time.time() - startTime
</span><del>- self.log.info("Calendar user search for %s matched %d records (%s) in %.2f seconds" % (tokens, len(records), typeCountsStr, totalTime))
</del><ins>+ self.log.info(
+ "Calendar user search for {tokens} matched {recordCount!d} "
+ "records ({typeCount}) in {time!.2f} seconds",
+ 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"> """
</span><span class="cx"> records = []
</span><span class="cx">
</span><del>- self.log.debug("Performing principal property search for %s" % (fields,))
</del><ins>+ self.log.debug(
+ "Performing principal property search for {fields}", 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("LDAP search %s %s %s" %
- (ldap.dn.dn2str(base), scope, filterstr))
</del><ins>+ self.log.debug(
+ "LDAP search {base} {scope} {filter}",
+ 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("LDAP search returned %d results" % (len(results),))
</del><ins>+ self.log.debug(
+ "LDAP search returned {count} results", 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("%d %s records are missing %s" %
- (numMissingGuids, recordType, guidAttr))
</del><ins>+ self.log.warn(
+ "{count!d} {type} records are missing {attr}",
+ count=numMissingGuids, type=recordType, attr=guidAttr
+ )
</ins><span class="cx">
</span><span class="cx"> if numMissingRecordNames:
</span><del>- self.log.warn("%d %s records are missing record name" %
- (numMissingRecordNames, recordType))
</del><ins>+ self.log.warn(
+ "{count!d} {type} records are missing record name",
+ count=numMissingRecordNames, type=recordType,
+ )
</ins><span class="cx">
</span><del>- self.log.debug("Principal property search matched %d records" % (len(records),))
</del><ins>+ self.log.debug(
+ "Principal property search matched {count} records",
+ 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 = "(%s=%s)" % (memberIdAttr, ldapEsc(memberId))
</span><del>- self.log.debug("Retrieving subtree of %s with filter %s" %
- (ldap.dn.dn2str(base), filterstr),
- system="LdapDirectoryService")
</del><ins>+ self.log.debug(
+ "Retrieving subtree of {base} with filter {filter}",
+ base=ldap.dn.dn2str(base), filter=filterstr,
+ system="LdapDirectoryService"
+ )
</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("Retrieving %s." % memberId,
- system="LdapDirectoryService")
</del><ins>+ self.log.debug(
+ "Retrieving {id}.",
+ id=memberId, system="LdapDirectoryService"
+ )
</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("Retrieved: %s %s" % (dn, attrs))
</del><ins>+ self.log.debug("Retrieved: {dn} {attrs}", 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("Unable to map %s to a record type" % (dn,))
</del><ins>+ self.log.error(
+ "Unable to map {dn} to a record type", 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"> ["(%s=%s)" % (a, self._memberId) for a in membersAttrs]
</span><span class="cx"> ),
</span><span class="cx"> )
</span><del>- self.log.debug("Finding groups containing %s" % (self._memberId,))
</del><ins>+ self.log.debug("Finding groups containing {id}", 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, "cn")
</span><del>- self.log.debug("%s is a member of %s" % (self._memberId, shortName))
</del><ins>+ self.log.debug(
+ "{id} is a member of {shortName}",
+ 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("{e}", 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("Invalid credentials for {dn}",
- dn=repr(self.dn),
- system="LdapDirectoryService")
</del><ins>+ self.log.info(
+ "Invalid credentials for {dn}",
+ dn=repr(self.dn), system="LdapDirectoryService"
+ )
</ins><span class="cx"> return False
</span><span class="cx">
</span><span class="cx"> else:
</span><del>- self.log.error("Unknown Authentication Method '{method}'",
- method=self.service.authMethod.upper())
</del><ins>+ self.log.error(
+ "Unknown Authentication Method {method!r}",
+ 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>