Skip to content

LDAP login with username#75

Merged
dannon merged 5 commits intogalaxyproject:devfrom
dtrudg:ldapsupport2
Apr 6, 2015
Merged

LDAP login with username#75
dannon merged 5 commits intogalaxyproject:devfrom
dtrudg:ldapsupport2

Conversation

@dtrudg
Copy link
Contributor

@dtrudg dtrudg commented Apr 2, 2015

This is my first attempt at messing up the galaxy auth to do what I want ;-) Looking for any kind of early comments so that I might eventually end up with a reasonable PR that would be useful to others. Am attempting to implement more generic auth support, particularly for use with LDAP. Per discussion on trello card https://trello.com/c/sxz9SM2R

Things I've messed with so far...

  • Changed the minimum length for galaxy public usernames to 3 char. We have lots of 3 char names using an initial + surname scheme for usernames in LDAP e.g. 'bli' or 'ydu'. Noticed for toolshed it's already a 3 char limit - so guessing changing the main limit to 3 chars might break something?!
  • Rename the activedirectory auth plugin to a more generic ldap_ad and add username auth functionality.
  • Provider authenticate methods now have to return email and username.
  • Hack of the user controller so that login tries to pull out a user from DB on an email or username match (not just email).
  • I've tried to change names for vars that might now contain a username or email to 'login' to avoid confusion over a var named 'email' containing a username and vice versa.

Am sure there are better ways to do most of these things, and I'll keep trying to find them and tidy up - but it seems to work for our need to auth against our LDAP using usernames.

Config Example

The option login-use-username in auth_conf.xml for the ldap_ad provider will use usernames instead of email for auth. For auto registration, both email and username sources must now be specified. E.g.

<?xml version="1.0"?>
<auth>
<authenticator>
  <type>ldap_ad</type>
  <options>
    <allow-register>No</allow-register>
    <auto-register>Yes</auto-register>
    <server>ldap://<server-address></server>
    <search-filter>(uid={login})</search-filter>
    <search-base>ou=users,dc=biohpc,dc=swmed,dc=edu</search-base>
    <search-fields>uid,mail</search-fields>
    <bind-user>{dn}</bind-user>
    <bind-password>{password}</bind-password>
    <continue-on-failure>False</continue-on-failure>
    <auto-register-username>{uid}</auto-register-username>
    <auto-register-email>{mail}</auto-register-email>
    <login-use-username>True</login-use-username>  
</options>
</authenticator>
</auth>
```xml

@hexylena
Copy link
Member

hexylena commented Apr 2, 2015

+1 from me,

  • thanks, username/email is better than just email since we support bare usernames since we don't handle multiple domains
  • The remote user login already submitted 3 character usernames (mine is esr and it was forced into the DB) so it shouldn't cause issues (or at least I didn't see any)
  • I'm a bit worried about hacking on the user controller, someone else should comment on that.

again, untested, but LGTM.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this changing? Also the condition does not correspond with the return message.
Note that TS has 3 and Galaxy 4 char username min length limit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comments in PR, our LDAP allows 3 character usernames (as do many others), and if my memory is correct (we've since changed a few things) REMOTE_USER forced esrinto the database despite Galaxy not explicity permitting it. I don't remember my public-name ending with a -.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. In that case the message should also state 3 though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If 3 is ok then doesn't need separate logic for tool shed and I'll tidy that. Was in a rush to push a PR to get some initial comments on direction as have had to switch to a different project for a bit. Will do some tidying at home. Thanks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I would not rush into lowering the requirements of 4 char min as others might chime in with different insights though.

@martenson
Copy link
Member

Overall this looks like a great start and awesome contribution! Thank you.
I need to test it more before supporting it but I like it so far. Few notes:

  • Would be great if TravisCI tests pass (some of your changes fail on PEP8).
  • I think form for creation of the users needs to be adjusted to reflect changes in username requirement (I think there is client-side validation too).

I will happily help you with these and others in the start of the next week.
Thanks again.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This first() is troublesome. I suspect it is a remnant of inconsistent DB on Main back when we did not enforce email to be unique nor valid. Username uniqueness is DB-enforced so it should not change anything but we might want to think about how to do this right. I like using .one() and catching exceptions from sqlalchemy (as in https://github.com/galaxyproject/galaxy/blob/dev/lib/galaxy/managers/libraries.py#L39)
Other ideas?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I never really think .one() should be used if it's okay a record doesn't exist, and that leads onto valid code. Not a fan of using exceptions for flow-control logic like that.

In this particular case it's perfectly okay for a user record not to exist - as we then go into the auto registration code. Not really an exception, just flow control logic.

What about doing a .count() and throwing an exception if >1 records match, doing the auto reg if 0 etc.. ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

count() is fine with me

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding one/first, http://alextechrants.blogspot.com/2013/11/10-common-stumbling-blocks-for.html has a decent description of the correct usage. When I asked for a little more info in the sqlalchemy IRC channel, the gist was: one() only when the record should exist barring some error; first() is to be used when the record may or may not exist and either one of those outcomes is ok. Verifying that there aren't multiple user emails (or whatever other field) should be enforced within the DB by unique constraints on the email column, and should not require a separate query each time we want to look something up.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you can do .all() and check len() in Python to prevent second query.

dtrudg added 2 commits April 3, 2015 21:55
Assuming 3 character username is okay, update the info and registration
forms. NB - username regex in register.mako already allowed 3 char. In
info.mako was 4 char.
@dtrudg
Copy link
Contributor Author

dtrudg commented Apr 4, 2015

@martenson Assuming 3 character username is okay, updated the info and registration
mako templates - JS and text. NB - username_re regex in register.mako already allowed 3 char. In
info.mako was 4 char.

@dannon
Copy link
Member

dannon commented Apr 6, 2015

Changing the minimum to 3 characters seems totally fine to me. Nice work here, @dctrud!

@blankenberg
Copy link
Member

We have some 3 character usernames in usegalaxy.org, so it shouldn't cause an issue.

@martenson
Copy link
Member

I have tested login/registration/update basics of this PR and did not find a problem. I tried try to test this with some fake-ldap-provider tool but nothing worked well for me (not fail of this code).

Also I do not think you have to solve our .first() issue so do not worry about it in this PR.

This looks ready to me.
👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LDAPAD is fine for a class/plugin name but I would prefer if it were just LDAP. Can we just make this ldap and the class LDAP?

Then toward the bottom of the file define

class ActiveDirectory(LDAP):
     """ Effectively just an alias for LDAP auth, but may contain active directory specific
     logic in the future. """
     plugin_type = 'activedirectory'

__all__ = ['LDAP', 'ActiveDirectory']

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable to me. Keep the module as ldap_ad.py to avoid clash with the python-ldap ldap module?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure - sounds like a good plan.

@dannon
Copy link
Member

dannon commented Apr 6, 2015

+1

@dtrudg
Copy link
Contributor Author

dtrudg commented Apr 6, 2015

Removing WIP in hope that this can be merged now if useful. Won't be able to work on other things I mentioned on the trello card for a while.

@dtrudg dtrudg changed the title Initial attempt at LDAP login with username - WIP Initial attempt at LDAP login with username Apr 6, 2015
@dtrudg dtrudg changed the title Initial attempt at LDAP login with username LDAP login with username Apr 6, 2015
@dannon
Copy link
Member

dannon commented Apr 6, 2015

Thanks for the update, looks good!

@jmchilton
Copy link
Member

I'll add my 👍 to the chorus - thanks @dctrud - this is awesome!

dannon added a commit that referenced this pull request Apr 6, 2015
@dannon dannon merged commit ffe58de into galaxyproject:dev Apr 6, 2015
@dtrudg
Copy link
Contributor Author

dtrudg commented Apr 6, 2015

Guess follow up is to ensure Wiki is updated, and reflects these additional changes? Do I need to contribute on that?

@martenson
Copy link
Member

I added a checklist for documentation to the trello card. We need to streamline the scattered information into one authentication wiki page/hub. Your contributions are welcomed but not required.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presently the type in this example should be ldap.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch!

@nsoranzo
Copy link
Member

nsoranzo commented May 1, 2015

I just noticed that this broke the <filter> tag of config/auth_conf.xml . In fact, active_authenticators() method in lib/galaxy/auth/__init__.py is now receiving a galaxy.model.User when called from check_password() and check_change_password(), an email address when called by check_registration_allowed(), and an email/username when called by check_auto_registration().

I'll try to work on a fix next week.

nsoranzo added a commit to nsoranzo/galaxy that referenced this pull request May 5, 2015
… revert changes in auth_conf.xml syntax.

After galaxyproject#75 , the <filter> tag of
config/auth_conf.xml is broken, see galaxyproject#75 (comment) .
I don't think that there is a meaningful way to filter on usernames, so I
changed it to filter on email instead of login.
Also:
- fix AuthManager.check_registration_allowed to use both email and username
  since which is used for login depends on the AuthProvider used;
- move ldap <authenticator> example to config/auth_conf.xml.sample .
nsoranzo added a commit to nsoranzo/galaxy that referenced this pull request May 5, 2015
… revert changes in auth_conf.xml syntax.

After galaxyproject#75 , the <filter> tag of
config/auth_conf.xml is broken, see galaxyproject#75 (comment) .
I don't think that there is a meaningful way to filter on usernames, so I
changed it to filter on email instead of login.
Also:
- fix AuthManager.check_registration_allowed to use both email and username
  since which is used for login depends on the AuthProvider used;
- move ldap <authenticator> example to config/auth_conf.xml.sample .
nsoranzo added a commit to nsoranzo/galaxy that referenced this pull request May 5, 2015
… revert changes in auth_conf.xml syntax.

After galaxyproject#75 , the <filter> tag of
config/auth_conf.xml is broken, see galaxyproject#75 (comment) .
I don't think that there is a meaningful way to filter on usernames, so I
changed it to filter on email instead of login.
Also:
- fix AuthManager.check_registration_allowed to use both email and username
  since which is used for login depends on the AuthProvider used;
- move ldap <authenticator> example to config/auth_conf.xml.sample .
mvdbeek pushed a commit to mvdbeek/galaxy that referenced this pull request Jan 24, 2017
Preparation for new Tool class in BioBlend.objects
sveinugu added a commit to elixir-oslo/proto that referenced this pull request Oct 31, 2018
…ello_sbKLjewQ

Ugly hack of track vs same track bug
blankenberg pushed a commit to blankenberg/galaxy that referenced this pull request Aug 14, 2019
simonbray pushed a commit to simonbray/galaxy that referenced this pull request Sep 22, 2020
Askomics GxIT: fix crash when no input selected
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants