-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplify auth.authenticate #2728
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ | |
|
||
import nav.errors | ||
from nav.config import NAVConfigParser | ||
from nav.models.profiles import Account, AccountGroup | ||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
@@ -121,11 +122,66 @@ | |
return lconn | ||
|
||
|
||
def authenticate(login, password): | ||
def authenticate(username, password): | ||
""" | ||
Attempt to authenticate the login name with password against the | ||
configured LDAP server. If the user is authenticated, required | ||
group memberships are also verified. | ||
Authenticate the username and password against the configured LDAP server. | ||
|
||
Required group memberships are also verified. | ||
|
||
Returns an authenticated Account with updated groups, or None. | ||
""" | ||
if not available: | ||
return None | ||
ldap_user = get_ldap_user(username, password) | ||
try: | ||
account = Account.objects.get(login__iexact=username, ext_sync='ldap') | ||
except Account.DoesNotExist: | ||
if ldap_user: | ||
account = autocreate_ldap_user(ldap_user, password) | ||
return account | ||
if account.locked: | ||
_logger.info("Locked user %s tried to log in", account.login) | ||
return None | ||
if account.check_password(password): | ||
account = update_ldap_user(ldap_user, account, password) | ||
return account | ||
Comment on lines
+125
to
+147
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This got confusing, real fast. I read this as: If a re-visiting user is authenticated via LDAP, this additionally checks their entered password against the password stored in the DB. If their LDAP password changed at some point, this local verification will fail, and the user can no longer log in to NAV. Then I realized that this function is actually only ever called for first-time users. The function contains code to handle the difference between new users and re-visiting users. It won't work well for re-visiting users, if I'm reading it correctly, but it will also never be called for re-visiting users, so what's the plan here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is confusing: it's partially duplicating what It will be called for re-visiting users once we split up
See my comment above about the fact that what happens if The hope is that we will one day have a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, is the change you want a flow-chart? |
||
return None | ||
|
||
|
||
def autocreate_ldap_user(ldap_user, password): | ||
account = Account( | ||
login=ldap_user.username, | ||
name=ldap_user.get_real_name(), | ||
ext_sync='ldap', | ||
) | ||
account = update_ldap_user(ldap_user, account, password) | ||
return account | ||
|
||
|
||
def update_ldap_user(ldap_user, account, password): | ||
account.set_password(password) | ||
account.save() | ||
_handle_ldap_admin_status(ldap_user, account) | ||
return account | ||
|
||
|
||
def _handle_ldap_admin_status(ldap_user, nav_account): | ||
is_admin = ldap_user.is_admin() | ||
# Only modify admin status if an entitlement is configured in webfront.conf | ||
if is_admin is not None: | ||
admin_group = AccountGroup.objects.get(id=AccountGroup.ADMIN_GROUP) | ||
if is_admin: | ||
nav_account.groups.add(admin_group) | ||
else: | ||
nav_account.groups.remove(admin_group) | ||
|
||
|
||
def get_ldap_user(login, password): | ||
""" | ||
Fetch an LDAPUser from an ldap server if login and password matches. | ||
|
||
Returns an autenticated LDAPUser of a specific group or with specific | ||
entitlements, or False. | ||
""" | ||
lconn = open_ldap() | ||
server = _config.get('ldap', 'server') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ldap_user
can be False, and thenupdate_ldap_user
will raise an exception. It is unclear what the best solution is though:Change the
if
to:If ldap_user is False authenticate will return None.
Split the
if
into two:Worse, the latter
if
might not be needed at all because if ldap_user is True, we have already been authenticated with ldap, so authenticating again is unneccessary.A third way is:
and then again choose whether to check the password again...