Add Active Directory backend which under most circumstance should be easier to setup than the LDAP backend

Review Request #699 — Created Jan. 14, 2009 and submitted

Information

Review Board SVN (deprecated)

Reviewers

The LDAP backend is too confusing to setup for most users of active directory. This Active Directory backend should make it much easier to get up and running with ReviewBoard in an AD environment. A user can just specify the domain name (ie. example.com) and check the option to use DNS to find the DC servers and everything else will be taken care of for them. Finding the domain controllers from DNS requires PyDNS. There is also the option of specifying the domain controller manually.

An OU can be specified optionally which will restrict users to those that belong in that OU. Users can also be required to belong to a certain group and recursive group checks are implemented when specifying a recursion depth greater than 0.
A patched version of Review Board is deployed internally, authenticating against Active Directory using DNS to find the domain controllers and with users restricted to a specified group. Extensive manual testing was performed of several combinations but I haven't figured out how to mock everything needed for an automated test suite.
chipx86
  1. This is great. I'd love to get this for the 1.0 release.
    
    Some changes before it goes in. Most are stylistic.
    1. Thanks. I responded to a few of your comments where I had a question or needed to clarify something. Everything else should be addressed in the latest patch.
  2. /trunk/reviewboard/accounts/backends.py (Diff revision 1)
     
     
    Shouldn't remove this line. 2 blank lines after imports.
  3. /trunk/reviewboard/accounts/backends.py (Diff revision 1)
     
     
     
     
    Two blank lines between classes.
  4. /trunk/reviewboard/accounts/backends.py (Diff revision 1)
     
     
     
    Remove the blank line after this class.
  5. /trunk/reviewboard/accounts/backends.py (Diff revision 1)
     
     
     
     
     
     
     
    This can be condensed to:
    
    return (settings.AD_RECURSION_DEPTH == -1 or
            depth <= settings.AD_RECURSION_DEPTH)
  6. /trunk/reviewboard/accounts/backends.py (Diff revision 1)
     
     
    A little more context would be good here. It should have a prefix of the backend name, and include the function name.
    
    Same with other logging statements in this file.
    1. I added a bit more context to the other logging statements in the ActiveDirectory backend by prefixing them with the "Active Directory" string. 
      
      I don't usually include function names in warning or error messages as I think they simply clutter up the log file for the person administering the application. If I need to debug something I can easily track down where the log statement occurs. Also, the other logging statements in LDAPBackend do not include the function name in the logging messages so for consistency I left that out. 
      
      However I can easily change all the logging statements in that file to a format you think is more helpful. Should I add something like ClassName.function as a prefix to all the log statements in backends.py?
    2. That's fine, the "Active Directory" string is enough. Good points with the logging. If these were "DEBUG" strings, then function names would be more useful, but as a warning it's fine.
  7. /trunk/reviewboard/accounts/backends.py (Diff revision 1)
     
     
    Space before "port="
  8. /trunk/reviewboard/accounts/backends.py (Diff revision 1)
     
     
    Space before "="
  9. /trunk/reviewboard/accounts/backends.py (Diff revision 1)
     
     
     
    Why is this temporary? Can you document it, and include a "XXX" at the beginning of the comment to indicate it?
    1. I forgot to remove this after debugging something. It's fixed in the latest patch.
  10. /trunk/reviewboard/accounts/backends.py (Diff revision 1)
     
     
     
    I think these default to False.
    1. I've copied that from the LDAPBackend. If they do default to False (which seems like the logical default) perhaps they should be removed from the other backends as well. Should I remove them just from the ActiveDirectoryBackend for now?
    2. It's fine, we'll clean up all these in one go later.
  11. /trunk/reviewboard/admin/checks.py (Diff revision 1)
     
     
     
     
    No blank line here.
  12. /trunk/reviewboard/admin/checks.py (Diff revision 1)
     
     
     
    The wording seemed a little confusing to me at first. Maybe something like:
    
    "PyDNS, which is required to find the domain controller, is not installed."
  13. /trunk/reviewboard/admin/checks.py (Diff revision 1)
     
     
    No blank line at the end of the file.
  14. /trunk/reviewboard/admin/forms.py (Diff revision 1)
     
     
     
    Should be in alphabetical order.
  15. /trunk/reviewboard/admin/forms.py (Diff revision 1)
     
     
     
     
    Can you reorder "Active Directory" above "LDAP"?
  16. /trunk/reviewboard/admin/forms.py (Diff revision 1)
     
     
     
     
    Good question. We should fix that :) Can you remove the comment though? We can fix this separately.
    
    Any reason the code to disable the field is commented out?
    1. Turns out get_can_enable_dns was broken and during debugging I commented out this line then forgot to fix the bug and uncomment it. The newest patch addresses this bug.
  17. 
      
CS
Review request changed
Change Summary:
This updated patch addresses the previous style issues, adds a bit more context to the logs, added start_tls to the ldap connection if TLS is requested for AD (which I missed previously) and fixes the bug in get_can_enable_dns by using "import DNS" instead of imp.find_module (I don't know much about how imp works but it fails to find the DNS module even when import DNS works).
chipx86
  1. This looks good. Thanks! Committed in r1678.
  2.