Since we made ZulipLDAPException a subclass of
_LDAPUser.AuthenticationFailed, the django-auth-ldap library already
handles catching it and returning None.
This fixes missing test coverage in this function introduced by
73e8bba379.
The main `authenticate` method in the django_auth_ldap package logs a message
at `exception` level if it passes through an exception it wasn't expecting.
Sensible practice, but we'd been passing through just such an exception for
any kind of routine authentication failure. After we recently stopped suppressing
an arbitrary subset of loggers with `disable_existing_loggers`, these started
showing up noisily, including in tests.
So, make our exceptions expected. Just like our own code, the upstream code
raises exceptions of a particular type for routine auth failures, and catches
them and just returns None. We make our type derive from that one, so as to
just piggyback on that behavior.
Fixes an issue reported in a comment to #6674.
This commit enables user to authenticate with any attribute set in
AUTH_LDAP_USER_SEARCH given that LDAP_EMAIL_ATTR is set to an email
attributes in the ldap server. Thus email and username can be
completely unrelated.
With some tweaks by tabbott to squash in the documentation and make it
work on older servers.
I was too hasty in pushing this -- it looks right logically, but it
breaks a test. May not be hard to fix forward, but reverting now to
unbreak the build in master.
This reverts commit 02acd467b4.
The whole thing is an error, so "message" is a more apt word for the
error message specifically. We abbreviate that as `msg` in the actual
HTTP responses and in the signatures of `json_error` and friends, so
do the same here.
This completes a major redesign of the Zulip login and registration
pages, making them look much more slick and modern.
Major features include:
* Display of the realm name, description and icon on the login page
and registration pages in the subdomains case.
* Much slicker looking buttons and input fields.
* A new overall style for the exterior of these portico pages.
This commit makes sure that GitHubAuthBackend will only authenticate
using its own authenticate method. This is done by adding a new
Python Social Auth strategy which instead of calling authenticate
method of Django, calls the authenticate of the backend directly.
The problem this commit solves is that while authenticating through
GitHub backend, we were ending up getting authenticated through
ZulipDummyBackend. This might happen because the default strategy used
by Python Social Auth calls the authenticate method of Django which
iterates over all the backends and tries the authenticate methods
which match with the function arguments. The new strategy this commit
adds calls the authenticate method of GitHub backend directly which
makes sense because we already know that we want to authenticate with
GithHub.
The actual problem of why we are ending up on ZulipDummyBackend is
still a mystery because the function arguments passed to its
authenticate method are different. It shouldn't be called.
Django tries to authenticate against all backends one by one.
The authenticate() function of GitHub backend used to take
*args and **kwargs arguments due to which it could be called
against any set of arguments. Django uses arguments to
differentiate authenticate() methods.
I believe this completes the project of ensuring that our recent work
on limiting what characters can appears in users' full names covers
the entire codebase.
In case realms have subdomains and the user hasn't been populated
yet in the Django User model, `ZulipLDAPAuthBackend` should not
rely on user's email domain to determine in which realm it should
be created in.
Fixes: #2227.
This makes it possible to configure only certain authentication
methods to be enabled on a per-realm basis.
Note that the authentication_methods_dict function (which checks what
backends are supported on the realm) requires an in function import
due to a circular dependency.
The actual logic is that if the user already exists than the
function should return a False and if the user does not exist
the function should first create the user and return True.