mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge remote-tracking branch 'jmchilton/release_15.05' into dev
This commit is contained in:
@@ -1,5 +1,35 @@
|
||||
<?xml version="1.0"?>
|
||||
<auth>
|
||||
<!--<authenticator>
|
||||
<type>ldap</type>
|
||||
-->
|
||||
<!-- Filter users for which this authenticator applies. This is a Python
|
||||
expression which is evaluated after replacing instances of {email}
|
||||
and {username} with the corresponding user's values. -->
|
||||
<!-- <filter>'{email}'.endswith('@example.com')</filter>
|
||||
<options>
|
||||
<auto-register>True</auto-register>
|
||||
<server>ldap://dc1.example.com</server>
|
||||
-->
|
||||
<!-- If search-fields is not present, all other search-* elements are ignored -->
|
||||
<!-- <search-fields>sAMAccountName,mail</search-fields>
|
||||
<search-filter>(&(objectClass=user)(mail={email}))</search-filter>
|
||||
<search-base>dc=dc1,dc=example,dc=com</search-base>
|
||||
-->
|
||||
<!-- If search-user not specified will bind anonymously to LDAP for search -->
|
||||
<!-- <search-user>jsmith</search-user>
|
||||
<search-password>mysecret</search-password>
|
||||
<bind-user>{sAMAccountName}@example.com</bind-user>
|
||||
<bind-password>{password}</bind-password>
|
||||
<auto-register-username>{sAMAccountName}</auto-register-username>
|
||||
<auto-register-email>{mail}</auto-register-email>
|
||||
-->
|
||||
<!-- To allow login with username instead of email, default is False -->
|
||||
<!-- <login-use-username>True</login-use-username>
|
||||
</options>
|
||||
</authenticator>
|
||||
-->
|
||||
|
||||
<authenticator>
|
||||
<type>localdb</type>
|
||||
<options>
|
||||
|
||||
+15
-34
@@ -18,31 +18,6 @@ from galaxy.util import plugin_config
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# <auth>
|
||||
# <authenticator>
|
||||
# <type>ldap</type>
|
||||
# <filter>'[login]'.endswith('@students.latrobe.edu.au')</filter>
|
||||
# <options>
|
||||
# <auto-register>True</auto-register>
|
||||
# <server>ldap://STUDENTS.ltu.edu.au</server>
|
||||
# [<search-filter>(&(objectClass=user)(mail={login}))</search-filter>
|
||||
# <search-base>dc=STUDENTS,dc=ltu,dc=edu,dc=au</search-base>
|
||||
# <!-- If search-user not specified will bind anonymously to LDAP for search -->
|
||||
# <search-user>jsmith</search-user>
|
||||
# <search-password>mysecret</search-password>
|
||||
# <search-fields>sAMAccountName,mail</search-fields>]
|
||||
# <bind-user>{sAMAccountName}@STUDENTS.ltu.edu.au</bind-user>
|
||||
# <bind-password>{password}</bind-password>
|
||||
# <auto-register-username>{sAMAccountName}</auto-register-username>
|
||||
# <auto-register-email>{mail}</auto-register-email>
|
||||
# <!-- To allow login with username instead of email
|
||||
# <login-use-username>True</login-use-username>
|
||||
# -->
|
||||
# </options>
|
||||
# </authenticator>
|
||||
# ...
|
||||
# </auth>
|
||||
|
||||
|
||||
class AuthManager(object):
|
||||
|
||||
@@ -85,14 +60,14 @@ class AuthManager(object):
|
||||
authenticators.append(authenticator)
|
||||
self.authenticators = authenticators
|
||||
|
||||
def check_registration_allowed(self, login, password):
|
||||
def check_registration_allowed(self, email, username, password):
|
||||
"""Checks if the provided email/username is allowed to register."""
|
||||
message = ''
|
||||
status = 'done'
|
||||
for provider, options in self.active_authenticators(login, password):
|
||||
for provider, options in self.active_authenticators(email, username, password):
|
||||
allow_reg = _get_tri_state(options, 'allow-register', True)
|
||||
if allow_reg is None: # i.e. challenge
|
||||
auth_result, msg = provider.authenticate(login, password, options)
|
||||
auth_result, msg = provider.authenticate(email, username, password, options)
|
||||
if auth_result is True:
|
||||
break
|
||||
if auth_result is None:
|
||||
@@ -112,11 +87,17 @@ class AuthManager(object):
|
||||
Checks the username/email & password using auth providers in order.
|
||||
If a match is found, returns the 'auto-register' option for that provider.
|
||||
"""
|
||||
for provider, options in self.active_authenticators(login, password):
|
||||
if '@' in login:
|
||||
email = login
|
||||
username = None
|
||||
else:
|
||||
email = None
|
||||
username = login
|
||||
for provider, options in self.active_authenticators(email, username, password):
|
||||
if provider is None:
|
||||
log.debug( "Unable to find module: %s" % options )
|
||||
else:
|
||||
auth_result, auto_email, auto_username = provider.authenticate(login, password, options)
|
||||
auth_result, auto_email, auto_username = provider.authenticate(email, username, password, options)
|
||||
auto_email = str(auto_email).lower()
|
||||
auto_username = str(auto_username).lower()
|
||||
if auth_result is True:
|
||||
@@ -139,7 +120,7 @@ class AuthManager(object):
|
||||
|
||||
def check_password(self, user, password):
|
||||
"""Checks the username/email and password using auth providers."""
|
||||
for provider, options in self.active_authenticators(user, password):
|
||||
for provider, options in self.active_authenticators(user.email, user.username, password):
|
||||
if provider is None:
|
||||
log.debug( "Unable to find module: %s" % options )
|
||||
else:
|
||||
@@ -154,7 +135,7 @@ class AuthManager(object):
|
||||
"""Checks that auth provider allows password changes and current_password
|
||||
matches.
|
||||
"""
|
||||
for provider, options in self.active_authenticators(user, current_password):
|
||||
for provider, options in self.active_authenticators(user.email, user.username, current_password):
|
||||
if provider is None:
|
||||
log.debug( "Unable to find module: %s" % options )
|
||||
else:
|
||||
@@ -168,7 +149,7 @@ class AuthManager(object):
|
||||
return (False, 'Password change not supported')
|
||||
return (False, 'Invalid current password')
|
||||
|
||||
def active_authenticators(self, login, password):
|
||||
def active_authenticators(self, email, username, password):
|
||||
"""Yields AuthProvider instances for the provided configfile that match the
|
||||
filters.
|
||||
"""
|
||||
@@ -176,7 +157,7 @@ class AuthManager(object):
|
||||
for authenticator in self.authenticators:
|
||||
filter_template = authenticator.filter_template
|
||||
if filter_template:
|
||||
filter_str = filter_template.format(login=login, password=password)
|
||||
filter_str = filter_template.format(email=email, username=username, password=password)
|
||||
passed_filter = eval(filter_str, {"__builtins__": None}, {'str': str})
|
||||
if not passed_filter:
|
||||
continue # skip to next
|
||||
|
||||
@@ -16,15 +16,17 @@ class AuthProvider(object):
|
||||
""" Short string providing labelling this plugin """
|
||||
|
||||
@abc.abstractmethod
|
||||
def authenticate(self, login, password, options):
|
||||
def authenticate(self, email, username, password, options):
|
||||
"""
|
||||
Check that the username and password are correct.
|
||||
Check that the user credentials are correct.
|
||||
|
||||
NOTE: Used within auto-registration to check it is ok to register this
|
||||
user.
|
||||
|
||||
:param login: the user's email address or username
|
||||
:type login: str
|
||||
:param email: the user's email address
|
||||
:type email: str
|
||||
:param username: the user's username
|
||||
:type username: str
|
||||
:param password: the plain text password they typed
|
||||
:type password: str
|
||||
:param options: options provided in auth_config_file
|
||||
@@ -44,8 +46,8 @@ class AuthProvider(object):
|
||||
NOTE: used on normal login to check authentication and update user
|
||||
details if required.
|
||||
|
||||
:param username: the user's email address or username
|
||||
:type username: str
|
||||
:param user: the user to authenticate
|
||||
:type user: galaxy.model.User
|
||||
:param password: the plain text password they typed
|
||||
:type password: str
|
||||
:param options: options provided in auth_config_file
|
||||
|
||||
@@ -16,7 +16,7 @@ class AlwaysReject(AuthProvider):
|
||||
"""
|
||||
plugin_type = 'alwaysreject'
|
||||
|
||||
def authenticate(self, login, password, options):
|
||||
def authenticate(self, email, username, password, options):
|
||||
"""
|
||||
See abstract method documentation.
|
||||
"""
|
||||
|
||||
@@ -30,26 +30,35 @@ class LDAP(AuthProvider):
|
||||
"""
|
||||
plugin_type = 'ldap'
|
||||
|
||||
def authenticate(self, login, password, options):
|
||||
def authenticate(self, email, username, password, options):
|
||||
"""
|
||||
See abstract method documentation.
|
||||
"""
|
||||
log.debug("Login: %s" % login)
|
||||
log.debug("Options: %s" % options)
|
||||
log.debug("LDAP authenticate: email is %s" % email)
|
||||
log.debug("LDAP authenticate: username is %s" % username)
|
||||
log.debug("LDAP authenticate: options are %s" % options)
|
||||
|
||||
failure_mode = False # reject but continue
|
||||
if options.get('continue-on-failure', 'False') == 'False':
|
||||
failure_mode = None # reject and do not continue
|
||||
|
||||
if _get_bool(options, 'login-use-username', False):
|
||||
if username is None:
|
||||
log.debug('LDAP authenticate: username must be used to login, cannot be None')
|
||||
return (failure_mode, '', '')
|
||||
else:
|
||||
if email is None:
|
||||
log.debug('LDAP authenticate: email must be used to login, cannot be None')
|
||||
return (failure_mode, '', '')
|
||||
|
||||
try:
|
||||
import ldap
|
||||
except:
|
||||
log.debug(
|
||||
"Login: %s, LDAP: False (could not load ldap module)" % (login))
|
||||
return (failure_mode, '')
|
||||
log.debug('LDAP authenticate: could not load ldap module')
|
||||
return (failure_mode, '', '')
|
||||
|
||||
# do LDAP search (if required)
|
||||
params = {'login': login, 'password': password}
|
||||
params = {'email': email, 'username': username, 'password': password}
|
||||
if 'search-fields' in options:
|
||||
try:
|
||||
# setup connection
|
||||
@@ -74,8 +83,8 @@ class LDAP(AuthProvider):
|
||||
# parse results
|
||||
_, suser = l.result(result, 60)
|
||||
dn, attrs = suser[0]
|
||||
log.debug(("LDAP dn: %s" % dn))
|
||||
log.debug(("LDAP Search attributes: %s" % attrs))
|
||||
log.debug(("LDAP authenticate: dn is %s" % dn))
|
||||
log.debug(("LDAP authenticate: search attributes are %s" % attrs))
|
||||
if hasattr(attrs, 'has_key'):
|
||||
for attr in attributes:
|
||||
if attr in attrs:
|
||||
@@ -84,7 +93,7 @@ class LDAP(AuthProvider):
|
||||
params[attr] = ""
|
||||
params['dn'] = dn
|
||||
except Exception:
|
||||
log.exception('LDAP Search Exception for login: %s' % login)
|
||||
log.exception('LDAP authenticate: search exception')
|
||||
return (failure_mode, '', '')
|
||||
# end search
|
||||
|
||||
@@ -97,10 +106,10 @@ class LDAP(AuthProvider):
|
||||
l.simple_bind_s(_get_subs(
|
||||
options, 'bind-user', params), _get_subs(options, 'bind-password', params))
|
||||
except Exception:
|
||||
log.exception('LDAP Authentication Exception for login %s' % login)
|
||||
log.exception('LDAP authenticate: bind exception')
|
||||
return (failure_mode, '', '')
|
||||
|
||||
log.debug("Login: %s, LDAP: True" % (login))
|
||||
log.debug('LDAP authentication successful')
|
||||
return (True,
|
||||
_get_subs(options, 'auto-register-email', params),
|
||||
_get_subs(options, 'auto-register-username', params))
|
||||
@@ -109,11 +118,7 @@ class LDAP(AuthProvider):
|
||||
"""
|
||||
See abstract method documentation.
|
||||
"""
|
||||
|
||||
if _get_bool(options, 'login-use-username', False):
|
||||
return self.authenticate(user.username, password, options)[0]
|
||||
else:
|
||||
return self.authenticate(user.email, password, options)[0]
|
||||
return self.authenticate(user.email, user.username, password, options)[0]
|
||||
|
||||
|
||||
class ActiveDirectory(LDAP):
|
||||
|
||||
@@ -13,7 +13,7 @@ class LocalDB(AuthProvider):
|
||||
"""Authenticate users against the local Galaxy database (as per usual)."""
|
||||
plugin_type = 'localdb'
|
||||
|
||||
def authenticate(self, login, password, options):
|
||||
def authenticate(self, email, username, password, options):
|
||||
"""
|
||||
See abstract method documentation.
|
||||
"""
|
||||
|
||||
@@ -58,8 +58,9 @@ class CollectlPlugin( InstrumentPlugin ):
|
||||
def __init__( self, **kwargs ):
|
||||
self.__configure_paths( kwargs )
|
||||
self.__configure_subsystems( kwargs )
|
||||
saved_logs_path = kwargs.get( "saved_logs_path", None )
|
||||
saved_logs_path = kwargs.get( "saved_logs_path", "" )
|
||||
if "app" in kwargs:
|
||||
log.debug("Found path for saved logs: %s" % saved_logs_path)
|
||||
saved_logs_path = kwargs[ "app" ].config.resolve_path( saved_logs_path )
|
||||
self.saved_logs_path = saved_logs_path
|
||||
self.__configure_collectl_recorder_args( kwargs )
|
||||
|
||||
@@ -37,6 +37,9 @@ class ToolBoxSearch( object ):
|
||||
self.index = self.storage.create_index( schema )
|
||||
writer = self.index.writer()
|
||||
for id, tool in self.toolbox.tools():
|
||||
# Do not add data managers to the public index
|
||||
if tool.tool_type == 'manage_data':
|
||||
continue
|
||||
add_doc_kwds = {
|
||||
"id": id,
|
||||
"name": to_unicode( tool.name ),
|
||||
|
||||
@@ -678,7 +678,7 @@ class User( BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Creat
|
||||
status = 'error'
|
||||
else:
|
||||
# check user is allowed to register
|
||||
message, status = trans.app.auth_manager.check_registration_allowed(email, password)
|
||||
message, status = trans.app.auth_manager.check_registration_allowed(email, username, password)
|
||||
if message == '':
|
||||
if not refresh_frames:
|
||||
if trans.webapp.name == 'galaxy':
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Import system subprocess now before twill so we don't get its
|
||||
# variant that breaks things.
|
||||
import subprocess
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
## Logo, layered over tabs to be clickable
|
||||
<div class="navbar-brand">
|
||||
<a href="${h.url_for( app.config.get( 'logo_url', '/' ) )}">
|
||||
<img border="0" src="${h.url_for('/static/images/galaxyIcon_noText.png')}">
|
||||
<img style="margin-left: 0.35em;" border="0" src="${h.url_for('/static/images/galaxyIcon_noText.png')}">
|
||||
Galaxy Tool Shed
|
||||
%if app.config.brand:
|
||||
<span>/ ${app.config.brand}</span>
|
||||
|
||||
Reference in New Issue
Block a user