Adds ability to use x.509 certificates for authenticating users

Review Request #991 — Created Aug. 24, 2009 and submitted

Review Board
These changes enable Review Board to use x.509 certificates to be used alongside the builtin username/password authentication backend. This functionality will be useful for deployments in environments with a Public Key Infrastructure set up.

I deliberately avoided modifying post-review to support client certificates due to a lack of decent support for them in Python's high-level libraries. Instead, I modified the user preferences view to permit authenticated users to set their Django password. Django's built-in support for multiple authentication backends will then permit them to use the builtin auth backend with post-review.

This diff was originally reviewed at
Tested on my test Review Board server, running Apache/mod_python,mod_ssl/Django 1.1.
  1. This is looking really good and I think after this round it'll be ready to go in. Just a few things I caught this time around that I'd like to see fixed. Most are pretty minor.
  2. reviewboard/accounts/ (Diff revision 2)
    Can you use TODO: instead?
  3. reviewboard/accounts/ (Diff revision 2)
    Wondering if we actually need to check for this. Presumably, if this code is even running, then this auth backend is configured. Otherwise it shouldn't be in the list.
    1. Hmm; I'm not sure how I missed this. It was originally intended to be a check for whether to autocreate a new user, and somehow I messed it up. It's fixed now.
  4. reviewboard/admin/ (Diff revision 2)
    Can we say where the field is from? "The [something] field" maybe.
    1. Yep. I've added a better description of where the field comes from.
  5. reviewboard/admin/ (Diff revision 2)
  6. reviewboard/admin/ (Diff revision 2)
    I believe you have to return the data from this function if it's valid.
    1. You're right. I only tested the failure case, so didn't notice that it was broken.
  7. reviewboard/admin/ (Diff revision 2)
    It's possible that we may get something down the road that is actually a subclass of this request type, rather than being that request type itself. For this reason, I think it may be better if we import these classes directly and use isinstance() to check.
  8. reviewboard/admin/ (Diff revision 2)
    It'd be really nice if we didn't have to access _req directly. Can we use os.getenv()? It looks like ModPythonHandler actually copies _req.subprocess_env into os.environ.
  9. reviewboard/admin/ (Diff revision 2)
    If this is ever not a string, then the user did something custom and stupid, and we don't want to mask it. We probably shouldn't use str() here.
    1. Done. When I first implemented this, I was getting an exception about env.get() not being able to accept unicode strings as the key to look up. That doesn't seem to be an issue when using the os.environ.get() call, though. I haven't tested the WSGI scenario.
Review request changed
  1. Thanks! Committed to master as r63c7a44.