mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge pull request #5238 from scholtalbers/feature/populate_ldap_user
add an admin form to pre-populate an ldap user
This commit is contained in:
@@ -25,6 +25,22 @@
|
||||
<!-- Whether users are allowed to change their password. Default is
|
||||
False. -->
|
||||
<!-- <allow-password-change>False</allow-password-change>
|
||||
-->
|
||||
<!-- Whether roles should be automatically created if
|
||||
the attribute specified under auto-register-roles can be found.
|
||||
Default is False. -->
|
||||
<!-- <auto-create-roles>False</auto-create-roles>
|
||||
-->
|
||||
<!-- Whether groups should be automatically created if
|
||||
the attribute specified under auto-register-roles can be found.
|
||||
Can be used in combination with auto-create-roles
|
||||
Default is False. -->
|
||||
<!-- <auto-create-groups>False</auto-create-groups>
|
||||
-->
|
||||
<!-- If set, roles will be assigned to the auto generated groups,
|
||||
not to the individual users. Can only be used if auto-create-roles and
|
||||
auto-create-groups are True. Default is False. -->
|
||||
<!-- <auto-assign-roles-to-groups-only>False</auto-assign-roles-to-groups-only>
|
||||
-->
|
||||
|
||||
<!-- LDAP-specific options -->
|
||||
@@ -88,12 +104,14 @@
|
||||
<bind-password>{password}</bind-password>
|
||||
<auto-register-username>{sAMAccountName}</auto-register-username>
|
||||
<auto-register-email>{mail}</auto-register-email>
|
||||
<auto-register-roles>{gidNumber}</auto-register-roles>
|
||||
-->
|
||||
<!-- For OpenLDAP: -->
|
||||
<!-- <bind-user>{dn}</bind-user>
|
||||
<bind-password>{password}</bind-password>
|
||||
<auto-register-username>{uid}</auto-register-username>
|
||||
<auto-register-email>{mail}</auto-register-email>
|
||||
<auto-register-roles>{gid}</auto-register-roles>
|
||||
-->
|
||||
<!-- </options>
|
||||
</authenticator>
|
||||
|
||||
@@ -1218,6 +1218,10 @@ galaxy:
|
||||
# Allow administrators to log in as other users (useful for debugging)
|
||||
#allow_user_impersonation: false
|
||||
|
||||
# When using LDAP for authentication, allow administrators to pre-
|
||||
# populate users using an additional form on 'Create new user'
|
||||
#show_user_prepopulate_form: false
|
||||
|
||||
# Allow users to remove their datasets from disk immediately
|
||||
# (otherwise, datasets will be removed after a time period specified
|
||||
# by an administrator in the cleanup scripts run via cron)
|
||||
|
||||
@@ -2562,6 +2562,17 @@
|
||||
:Type: bool
|
||||
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
``show_user_prepopulate_form``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
:Description:
|
||||
When using LDAP for authentication, allow administrators to pre-
|
||||
populate users using an additional form on 'Create new user'
|
||||
:Default: ``false``
|
||||
:Type: bool
|
||||
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
``allow_user_dataset_purge``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
+22
-59
@@ -3,11 +3,10 @@ Contains implementations of the authentication logic.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import xml.etree.ElementTree
|
||||
from collections import namedtuple
|
||||
|
||||
from galaxy.security.validate_user_input import validate_publicname
|
||||
from galaxy.util import plugin_config, string_as_bool
|
||||
from galaxy.auth.util import get_authenticators, parse_auth_results
|
||||
from galaxy.exceptions import Conflict
|
||||
from galaxy.util import string_as_bool
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -16,39 +15,7 @@ class AuthManager(object):
|
||||
|
||||
def __init__(self, app):
|
||||
self.__app = app
|
||||
import galaxy.auth.providers
|
||||
self.__plugins_dict = plugin_config.plugins_dict(galaxy.auth.providers, 'plugin_type')
|
||||
auth_config_file = app.config.auth_config_file
|
||||
# parse XML
|
||||
ct = xml.etree.ElementTree.parse(auth_config_file)
|
||||
conf_root = ct.getroot()
|
||||
|
||||
authenticators = []
|
||||
# process authenticators
|
||||
for auth_elem in conf_root:
|
||||
type_elem = auth_elem.find('type')
|
||||
plugin = self.__plugins_dict.get(type_elem.text)()
|
||||
|
||||
# check filterelem
|
||||
filter_elem = auth_elem.find('filter')
|
||||
if filter_elem is not None:
|
||||
filter_template = str(filter_elem.text)
|
||||
else:
|
||||
filter_template = None
|
||||
|
||||
# extract options
|
||||
options_elem = auth_elem.find('options')
|
||||
options = {}
|
||||
if options_elem is not None:
|
||||
for opt in options_elem:
|
||||
options[opt.tag] = opt.text
|
||||
authenticator = Authenticator(
|
||||
plugin=plugin,
|
||||
filter_template=filter_template,
|
||||
options=options,
|
||||
)
|
||||
authenticators.append(authenticator)
|
||||
self.authenticators = authenticators
|
||||
self.authenticators = get_authenticators(app.config.auth_config_file)
|
||||
|
||||
def check_registration_allowed(self, email, username, password):
|
||||
"""Checks if the provided email/username is allowed to register."""
|
||||
@@ -72,7 +39,7 @@ class AuthManager(object):
|
||||
break
|
||||
return message, status
|
||||
|
||||
def check_auto_registration(self, trans, login, password):
|
||||
def check_auto_registration(self, trans, login, password, no_password_check=False):
|
||||
"""
|
||||
Checks the username/email & password using auth providers in order.
|
||||
If a match is found, returns the 'auto-register' option for that provider.
|
||||
@@ -83,30 +50,29 @@ class AuthManager(object):
|
||||
else:
|
||||
email = None
|
||||
username = login
|
||||
auth_return = {
|
||||
"auto_reg": False,
|
||||
"email": "",
|
||||
"username": ""
|
||||
}
|
||||
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(email, username, password, options)
|
||||
auto_email = str(auto_email).lower()
|
||||
auto_username = str(auto_username).lower()
|
||||
if auth_result is True:
|
||||
# make username unique
|
||||
if validate_publicname(trans, auto_username) != '':
|
||||
i = 1
|
||||
while i <= 10: # stop after 10 tries
|
||||
if validate_publicname(trans, "%s-%i" % (auto_username, i)) == '':
|
||||
auto_username = "%s-%i" % (auto_username, i)
|
||||
break
|
||||
i += 1
|
||||
else:
|
||||
break # end for loop if we can't make a unique username
|
||||
log.debug("Email: %s, auto-register with username: %s" % (auto_email, auto_username))
|
||||
return (string_as_bool(options.get('auto-register', False)), auto_email, auto_username)
|
||||
elif auth_result is None:
|
||||
options['no_password_check'] = no_password_check
|
||||
auth_results = provider.authenticate(email, username, password, options)
|
||||
if auth_results[0] is True:
|
||||
try:
|
||||
auth_return = parse_auth_results(trans, auth_results, options)
|
||||
except Conflict:
|
||||
break
|
||||
return auth_return
|
||||
elif auth_results[0] is None:
|
||||
auto_email = str(auth_results[1]).lower()
|
||||
auto_username = str(auth_results[2]).lower()
|
||||
log.debug("Email: %s, Username %s, stopping due to failed non-continue" % (auto_email, auto_username))
|
||||
break # end authentication (skip rest)
|
||||
return (False, '', '')
|
||||
return auth_return
|
||||
|
||||
def check_password(self, user, password):
|
||||
"""Checks the username/email and password using auth providers."""
|
||||
@@ -157,9 +123,6 @@ class AuthManager(object):
|
||||
raise
|
||||
|
||||
|
||||
Authenticator = namedtuple('Authenticator', ['plugin', 'filter_template', 'options'])
|
||||
|
||||
|
||||
def _get_allow_register(d):
|
||||
s = d.get('allow-register', True)
|
||||
lower_s = str(s).lower()
|
||||
|
||||
@@ -10,6 +10,12 @@ from galaxy.exceptions import ConfigurationError
|
||||
from galaxy.util import string_as_bool
|
||||
from ..providers import AuthProvider
|
||||
|
||||
try:
|
||||
import ldap
|
||||
except ImportError as exc:
|
||||
ldap = None
|
||||
ldap_import_exc = exc
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -71,35 +77,51 @@ class LDAP(AuthProvider):
|
||||
"""
|
||||
plugin_type = 'ldap'
|
||||
|
||||
def authenticate(self, email, username, password, options):
|
||||
"""
|
||||
See abstract method documentation.
|
||||
"""
|
||||
log.debug("LDAP authenticate: email is %s" % email)
|
||||
log.debug("LDAP authenticate: username is %s" % username)
|
||||
log.debug("LDAP authenticate: options are %s" % options)
|
||||
def __init__(self):
|
||||
super(LDAP, self).__init__()
|
||||
self.auto_create_roles_or_groups = False
|
||||
self.role_search_attribute = None
|
||||
self.role_search_option = 'auto-register-roles'
|
||||
|
||||
def check_config(self, username, email, options):
|
||||
ok = True
|
||||
failure_mode = False # reject but continue
|
||||
if options.get('continue-on-failure', 'False') == 'False':
|
||||
failure_mode = None # reject and do not continue
|
||||
|
||||
if string_as_bool(options.get('login-use-username', False)):
|
||||
if username is None:
|
||||
if not username:
|
||||
log.debug('LDAP authenticate: username must be used to login, cannot be None')
|
||||
return (failure_mode, '', '')
|
||||
return ok, failure_mode
|
||||
else:
|
||||
if email is None:
|
||||
if not email:
|
||||
log.debug('LDAP authenticate: email must be used to login, cannot be None')
|
||||
return (failure_mode, '', '')
|
||||
return ok, failure_mode
|
||||
|
||||
try:
|
||||
import ldap
|
||||
except ImportError:
|
||||
log.debug('LDAP authenticate: could not load ldap module')
|
||||
return (failure_mode, '', '')
|
||||
auto_create_roles = string_as_bool(options.get('auto-create-roles', False))
|
||||
auto_create_groups = string_as_bool(options.get('auto-create-groups', False))
|
||||
self.auto_create_roles_or_groups = auto_create_roles or auto_create_groups
|
||||
auto_assign_roles_to_groups_only = string_as_bool(options.get('auto-assign-roles-to-groups-only', False))
|
||||
if auto_assign_roles_to_groups_only and not (auto_create_roles and auto_create_groups):
|
||||
raise ConfigurationError("If 'auto-assign-roles-to-groups-only' is True, auto-create-roles and "
|
||||
"auto-create-groups have to be True as well.")
|
||||
|
||||
# do LDAP search (if required)
|
||||
params = {'email': email, 'username': username, 'password': password}
|
||||
self.role_search_attribute = options.get(self.role_search_option, None)
|
||||
return ok, failure_mode
|
||||
|
||||
def ldap_search(self, email, username, options):
|
||||
config_ok, failure_mode = self.check_config(username, email, options)
|
||||
if ldap is None:
|
||||
raise RuntimeError("Failed to load LDAP module: %s", str(ldap_import_exc))
|
||||
|
||||
if not config_ok:
|
||||
return failure_mode, None
|
||||
|
||||
if self.auto_create_roles_or_groups and self.role_search_attribute is None:
|
||||
raise ConfigurationError("If 'auto-create-roles' or 'auto-create-groups' is True, a '%s' attribute has to"
|
||||
" be provided." % self.role_search_option)
|
||||
|
||||
params = {'email': email, 'username': username}
|
||||
|
||||
try:
|
||||
ldap_options_raw = _get_subs(options, 'ldap-options', params)
|
||||
@@ -116,7 +138,7 @@ class LDAP(AuthProvider):
|
||||
ldap.set_option(*opt)
|
||||
except Exception:
|
||||
log.exception('LDAP authenticate: set_option exception')
|
||||
return (failure_mode, '', '')
|
||||
return (failure_mode, None)
|
||||
|
||||
if 'search-fields' in options:
|
||||
try:
|
||||
@@ -140,23 +162,63 @@ class LDAP(AuthProvider):
|
||||
# parse results
|
||||
if suser is None or len(suser) == 0:
|
||||
log.warning('LDAP authenticate: search returned no results')
|
||||
return (failure_mode, '', '')
|
||||
return (failure_mode, None)
|
||||
dn, attrs = suser[0]
|
||||
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:
|
||||
if attr == self.role_search_attribute[1:-1]: # strip brackets
|
||||
# keep role names as list
|
||||
params[self.role_search_option] = attrs[attr]
|
||||
elif attr in attrs:
|
||||
params[attr] = str(attrs[attr][0])
|
||||
else:
|
||||
params[attr] = ""
|
||||
|
||||
if self.auto_create_roles_or_groups and self.role_search_option not in params:
|
||||
raise ConfigurationError("Missing or mismatching LDAP parameters for %s. Make sure the %s is "
|
||||
"included in the 'search-fields'." %
|
||||
(self.role_search_option, self.role_search_attribute))
|
||||
log.critical(params)
|
||||
params['dn'] = dn
|
||||
except Exception:
|
||||
log.exception('LDAP authenticate: search exception')
|
||||
return (failure_mode, '', '')
|
||||
# end search
|
||||
return (failure_mode, None)
|
||||
|
||||
# bind as user to check their credentials
|
||||
return failure_mode, params
|
||||
|
||||
def authenticate(self, email, username, password, options):
|
||||
"""
|
||||
See abstract method documentation.
|
||||
"""
|
||||
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, params = self.ldap_search(email, username, options)
|
||||
if not params:
|
||||
return failure_mode, '', ''
|
||||
|
||||
# allow to skip authentication to allow for pre-populating users
|
||||
if not options.get('no_password_check', False):
|
||||
params['password'] = password
|
||||
if not self._authenticate(params, options):
|
||||
return failure_mode, '', ''
|
||||
|
||||
attributes = {}
|
||||
if self.auto_create_roles_or_groups:
|
||||
attributes['roles'] = params[self.role_search_option]
|
||||
return (True,
|
||||
_get_subs(options, 'auto-register-email', params),
|
||||
_get_subs(options, 'auto-register-username', params),
|
||||
attributes)
|
||||
|
||||
def _authenticate(self, params, options):
|
||||
"""
|
||||
Do the actual authentication by binding as the user to check their credentials
|
||||
"""
|
||||
import ldap
|
||||
try:
|
||||
l = ldap.initialize(_get_subs(options, 'server', params))
|
||||
l.protocol_version = 3
|
||||
@@ -174,12 +236,9 @@ class LDAP(AuthProvider):
|
||||
raise RuntimeError('LDAP authenticate: anonymous bind')
|
||||
except Exception:
|
||||
log.warning('LDAP authenticate: bind exception', exc_info=True)
|
||||
return (failure_mode, '', '')
|
||||
|
||||
return False
|
||||
log.debug('LDAP authentication successful')
|
||||
return (True,
|
||||
_get_subs(options, 'auto-register-email', params),
|
||||
_get_subs(options, 'auto-register-username', params))
|
||||
return True
|
||||
|
||||
def authenticate_user(self, user, password, options):
|
||||
"""
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import logging
|
||||
import xml.etree.ElementTree
|
||||
from collections import namedtuple
|
||||
|
||||
import galaxy.auth.providers
|
||||
from galaxy.exceptions import Conflict
|
||||
from galaxy.security.validate_user_input import validate_publicname
|
||||
from galaxy.util import plugin_config, string_as_bool
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
Authenticator = namedtuple('Authenticator', ['plugin', 'filter_template', 'options'])
|
||||
|
||||
|
||||
def get_authenticators(auth_config_file):
|
||||
__plugins_dict = plugin_config.plugins_dict(galaxy.auth.providers, 'plugin_type')
|
||||
# parse XML
|
||||
ct = xml.etree.ElementTree.parse(auth_config_file)
|
||||
conf_root = ct.getroot()
|
||||
|
||||
authenticators = []
|
||||
# process authenticators
|
||||
for auth_elem in conf_root:
|
||||
type_elem = auth_elem.find('type')
|
||||
plugin = __plugins_dict.get(type_elem.text)()
|
||||
|
||||
# check filterelem
|
||||
filter_elem = auth_elem.find('filter')
|
||||
if filter_elem is not None:
|
||||
filter_template = str(filter_elem.text)
|
||||
else:
|
||||
filter_template = None
|
||||
|
||||
# extract options
|
||||
options_elem = auth_elem.find('options')
|
||||
options = {}
|
||||
if options_elem is not None:
|
||||
for opt in options_elem:
|
||||
options[opt.tag] = opt.text
|
||||
authenticator = Authenticator(
|
||||
plugin=plugin,
|
||||
filter_template=filter_template,
|
||||
options=options,
|
||||
)
|
||||
authenticators.append(authenticator)
|
||||
return authenticators
|
||||
|
||||
|
||||
def parse_auth_results(trans, auth_results, options):
|
||||
auth_return = {}
|
||||
auth_result, auto_email, auto_username = auth_results[:3]
|
||||
auto_email = str(auto_email).lower()
|
||||
auto_username = str(auto_username).lower()
|
||||
# make username unique
|
||||
if validate_publicname(trans, auto_username) != '':
|
||||
i = 1
|
||||
while i <= 10: # stop after 10 tries
|
||||
if validate_publicname(trans, "%s-%i" % (auto_username, i)) == '':
|
||||
auto_username = "%s-%i" % (auto_username, i)
|
||||
break
|
||||
i += 1
|
||||
else:
|
||||
raise Conflict("Cannot make unique username")
|
||||
log.debug("Email: %s, auto-register with username: %s" % (auto_email, auto_username))
|
||||
auth_return["auto_reg"] = string_as_bool(options.get('auto-register', False))
|
||||
auth_return["email"] = auto_email
|
||||
auth_return["username"] = auto_username
|
||||
auth_return["auto_create_roles"] = string_as_bool(options.get('auto-create-roles', False))
|
||||
auth_return["auto_create_groups"] = string_as_bool(options.get('auto-create-groups', False))
|
||||
auth_return["auto_assign_roles_to_groups_only"] = string_as_bool(
|
||||
options.get('auto-assign-roles-to-groups-only', False))
|
||||
|
||||
if len(auth_results) == 4:
|
||||
auth_return["attributes"] = auth_results[3]
|
||||
return auth_return
|
||||
@@ -286,6 +286,7 @@ class Configuration(object):
|
||||
self.allow_user_deletion = string_as_bool(kwargs.get("allow_user_deletion", "False"))
|
||||
self.allow_user_dataset_purge = string_as_bool(kwargs.get("allow_user_dataset_purge", "True"))
|
||||
self.allow_user_impersonation = string_as_bool(kwargs.get("allow_user_impersonation", "False"))
|
||||
self.show_user_prepopulate_form = string_as_bool(kwargs.get("show_user_prepopulate_form", "False"))
|
||||
self.new_user_dataset_access_role_default_private = string_as_bool(kwargs.get("new_user_dataset_access_role_default_private", "False"))
|
||||
self.collect_outputs_from = [x.strip() for x in kwargs.get('collect_outputs_from', 'new_file_path,job_working_directory').lower().split(',')]
|
||||
self.template_path = resolve_path(kwargs.get("template_path", "templates"), self.root)
|
||||
|
||||
@@ -776,6 +776,36 @@ class GalaxyRBACAgent(RBACAgent):
|
||||
return None
|
||||
return role
|
||||
|
||||
def get_role(self, name, type=None):
|
||||
type = type or self.model.Role.types.ADMIN
|
||||
# will raise exception if not found
|
||||
return self.sa_session.query(self.model.Role) \
|
||||
.filter(and_(self.model.Role.table.c.name == name,
|
||||
self.model.Role.table.c.type == type)) \
|
||||
.one()
|
||||
|
||||
def create_role(self, name, description, in_users, in_groups, create_group_for_role=False, type=None):
|
||||
type = type or self.model.Role.types.ADMIN
|
||||
role = self.model.Role(name=name, description=description, type=type)
|
||||
self.sa_session.add(role)
|
||||
# Create the UserRoleAssociations
|
||||
for user in [self.sa_session.query(self.model.User).get(x) for x in in_users]:
|
||||
self.associate_user_role(user, role)
|
||||
# Create the GroupRoleAssociations
|
||||
for group in [self.sa_session.query(self.model.Group).get(x) for x in in_groups]:
|
||||
self.associate_group_role(group, role)
|
||||
if create_group_for_role:
|
||||
# Create the group
|
||||
group = self.model.Group(name=name)
|
||||
self.sa_session.add(group)
|
||||
# Associate the group with the role
|
||||
self.associate_group_role(group, role)
|
||||
num_in_groups = len(in_groups) + 1
|
||||
else:
|
||||
num_in_groups = len(in_groups)
|
||||
self.sa_session.flush()
|
||||
return role, num_in_groups
|
||||
|
||||
def get_sharing_roles(self, user):
|
||||
return self.sa_session.query(self.model.Role) \
|
||||
.filter(and_((self.model.Role.table.c.name).like("Sharing role for: %" + user.email + "%"),
|
||||
|
||||
@@ -1905,6 +1905,14 @@ mapping:
|
||||
desc: |
|
||||
Allow administrators to log in as other users (useful for debugging)
|
||||
|
||||
show_user_prepopulate_form:
|
||||
type: bool
|
||||
default: false
|
||||
required: false
|
||||
desc: |
|
||||
When using LDAP for authentication, allow administrators to pre-populate users
|
||||
using an additional form on 'Create new user'
|
||||
|
||||
allow_user_dataset_purge:
|
||||
type: bool
|
||||
default: true
|
||||
|
||||
@@ -15,6 +15,7 @@ from sqlalchemy import (
|
||||
or_,
|
||||
true
|
||||
)
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
|
||||
from galaxy import (
|
||||
model,
|
||||
@@ -485,6 +486,77 @@ class User(BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Create
|
||||
form_input_auto_focus=True,
|
||||
active_view="user")
|
||||
|
||||
def __handle_role_and_group_auto_creation(self, trans, user, roles, auto_create_roles=False,
|
||||
auto_create_groups=False, auto_assign_roles_to_groups_only=False):
|
||||
for role_name in roles:
|
||||
role = None
|
||||
group = None
|
||||
if auto_create_roles:
|
||||
try:
|
||||
# first try to find the role
|
||||
role = trans.app.security_agent.get_role(role_name)
|
||||
except NoResultFound:
|
||||
# or create it
|
||||
role, num_in_groups = trans.app.security_agent.create_role(
|
||||
role_name, "Auto created upon user registration", [], [],
|
||||
create_group_for_role=auto_create_groups)
|
||||
if auto_create_groups:
|
||||
trans.log_event("Created role and group for auto-registered user.")
|
||||
else:
|
||||
trans.log_event("Created role for auto-registered user.")
|
||||
if auto_create_groups:
|
||||
# only create a group if not existing yet
|
||||
try:
|
||||
group = self.sa_session.query(trans.app.model.Group).filter(
|
||||
trans.app.model.Group.table.c.name == role_name).first()
|
||||
except NoResultFound:
|
||||
group = self.model.Group(name=role_name)
|
||||
self.sa_session.add(group)
|
||||
trans.app.security_agent.associate_user_group(user, group)
|
||||
|
||||
if auto_assign_roles_to_groups_only and group and role:
|
||||
trans.log_event("Assigning role to group only")
|
||||
trans.app.security_agent.associate_group_role(group, role)
|
||||
elif not auto_assign_roles_to_groups_only and role:
|
||||
trans.log_event("Assigning role to newly created user")
|
||||
trans.app.security_agent.associate_user_role(user, role)
|
||||
|
||||
def __autoregistration(self, trans, login, password, status, kwd, no_password_check=False, cntrller=None):
|
||||
"""
|
||||
Does the autoregistration if enabled. Returns a message
|
||||
"""
|
||||
skip_login_handling = cntrller == 'admin' and trans.user_is_admin()
|
||||
autoreg = trans.app.auth_manager.check_auto_registration(trans, login, password, no_password_check=no_password_check)
|
||||
user = None
|
||||
success = False
|
||||
if autoreg["auto_reg"]:
|
||||
kwd['email'] = autoreg["email"]
|
||||
kwd['username'] = autoreg["username"]
|
||||
message = " ".join([validate_email(trans, kwd['email']),
|
||||
validate_publicname(trans, kwd['username'])]).rstrip()
|
||||
if not message:
|
||||
message, status, user, success = self.__register(trans, cntrller, False, no_redirect=skip_login_handling, **kwd)
|
||||
if success:
|
||||
# The handle_user_login() method has a call to the history_set_default_permissions() method
|
||||
# (needed when logging in with a history), user needs to have default permissions set before logging in
|
||||
if not skip_login_handling:
|
||||
trans.handle_user_login(user)
|
||||
trans.log_event("User (auto) created a new account")
|
||||
trans.log_event("User logged in")
|
||||
if "attributes" in autoreg and "roles" in autoreg["attributes"]:
|
||||
self.__handle_role_and_group_auto_creation(
|
||||
trans, user, autoreg["attributes"]["roles"],
|
||||
auto_create_groups=autoreg["auto_create_groups"],
|
||||
auto_create_roles=autoreg["auto_create_roles"],
|
||||
auto_assign_roles_to_groups_only=autoreg["auto_assign_roles_to_groups_only"])
|
||||
else:
|
||||
message = "Auto-registration failed, contact your local Galaxy administrator. %s" % message
|
||||
else:
|
||||
message = "Auto-registration failed, contact your local Galaxy administrator. %s" % message
|
||||
else:
|
||||
message = "No such user or invalid password"
|
||||
return message, status, user, success
|
||||
|
||||
def __validate_login(self, trans, **kwd):
|
||||
"""Validates numerous cases that might happen during the login time."""
|
||||
status = kwd.get('status', 'error')
|
||||
@@ -499,26 +571,8 @@ class User(BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Create
|
||||
)).first()
|
||||
log.debug("trans.app.config.auth_config_file: %s" % trans.app.config.auth_config_file)
|
||||
if not user:
|
||||
autoreg = trans.app.auth_manager.check_auto_registration(trans, login, password)
|
||||
if autoreg[0]:
|
||||
kwd['email'] = autoreg[1]
|
||||
kwd['username'] = autoreg[2]
|
||||
message = " ".join([validate_email(trans, kwd['email']),
|
||||
validate_publicname(trans, kwd['username'])]).rstrip()
|
||||
if not message:
|
||||
message, status, user, success = self.__register(trans, 'user', False, **kwd)
|
||||
if success:
|
||||
# The handle_user_login() method has a call to the history_set_default_permissions() method
|
||||
# (needed when logging in with a history), user needs to have default permissions set before logging in
|
||||
trans.handle_user_login(user)
|
||||
trans.log_event("User (auto) created a new account")
|
||||
trans.log_event("User logged in")
|
||||
else:
|
||||
message = "Auto-registration failed, contact your local Galaxy administrator. %s" % message
|
||||
else:
|
||||
message = "Auto-registration failed, contact your local Galaxy administrator. %s" % message
|
||||
else:
|
||||
message = "No such user or invalid password"
|
||||
message, status, user, success = self.__autoregistration(trans, login, password, status, kwd)
|
||||
|
||||
elif user.deleted:
|
||||
message = "This account has been marked deleted, contact your local Galaxy administrator to restore the account."
|
||||
if trans.app.config.error_email_to is not None:
|
||||
@@ -670,12 +724,28 @@ class User(BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Create
|
||||
subscribe_checked = CheckboxField.is_checked(subscribe)
|
||||
referer = trans.request.referer or ''
|
||||
redirect = kwd.get('redirect', referer).strip()
|
||||
is_admin = cntrller == 'admin' and trans.user_is_admin
|
||||
is_admin = cntrller == 'admin' and trans.user_is_admin()
|
||||
show_user_prepopulate_form = is_admin and trans.app.config.show_user_prepopulate_form
|
||||
if not trans.app.config.allow_user_creation and not trans.user_is_admin():
|
||||
message = 'User registration is disabled. Please contact your local Galaxy administrator for an account.'
|
||||
if trans.app.config.error_email_to is not None:
|
||||
message += ' Contact: %s' % trans.app.config.error_email_to
|
||||
status = 'error'
|
||||
elif show_user_prepopulate_form and params.get('prepopulate_user_button', False):
|
||||
# pre-populate the user through a provider like ldap
|
||||
csrf_check = trans.check_csrf_token()
|
||||
if csrf_check:
|
||||
return csrf_check
|
||||
login = username if username else email
|
||||
message, status, user, success = self.__autoregistration(trans, login, '', status, kwd,
|
||||
no_password_check=True, cntrller=cntrller)
|
||||
if success:
|
||||
message = 'Prepopulated new user account (%s)' % escape(user.email)
|
||||
trans.response.send_redirect(web.url_for(controller='admin',
|
||||
action='users',
|
||||
cntrller=cntrller,
|
||||
message=message,
|
||||
status=status))
|
||||
else:
|
||||
# check user is allowed to register
|
||||
message, status = trans.app.auth_manager.check_registration_allowed(email, username, password)
|
||||
@@ -729,6 +799,7 @@ class User(BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Create
|
||||
email=email,
|
||||
username=transform_publicname(trans, username),
|
||||
subscribe_checked=subscribe_checked,
|
||||
show_user_prepopulate_form=show_user_prepopulate_form,
|
||||
use_panels=use_panels,
|
||||
redirect=redirect,
|
||||
redirect_url=redirect_url,
|
||||
@@ -737,7 +808,7 @@ class User(BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Create
|
||||
message=message,
|
||||
status=status)
|
||||
|
||||
def __register(self, trans, cntrller, subscribe_checked, **kwd):
|
||||
def __register(self, trans, cntrller, subscribe_checked, no_redirect=False, **kwd):
|
||||
email = util.restore_text(kwd.get('email', ''))
|
||||
password = kwd.get('password', '')
|
||||
username = util.restore_text(kwd.get('username', ''))
|
||||
@@ -762,13 +833,14 @@ class User(BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Create
|
||||
except Exception:
|
||||
log.exception('Subscribing to the mailing list has failed.')
|
||||
error = "Now logged in as " + user.email + ". However, subscribing to the mailing list has failed."
|
||||
|
||||
if not error and not is_admin:
|
||||
# The handle_user_login() method has a call to the history_set_default_permissions() method
|
||||
# (needed when logging in with a history), user needs to have default permissions set before logging in
|
||||
trans.handle_user_login(user)
|
||||
trans.log_event("User created a new account")
|
||||
trans.log_event("User logged in")
|
||||
elif not error:
|
||||
elif not error and not no_redirect:
|
||||
trans.response.send_redirect(web.url_for(controller='admin',
|
||||
action='users',
|
||||
message='Created new user account (%s)' % user.email,
|
||||
|
||||
@@ -89,27 +89,8 @@ class Admin(object):
|
||||
ok = False
|
||||
else:
|
||||
# Create the role
|
||||
role = trans.app.model.Role(name=name, description=description, type=trans.app.model.Role.types.ADMIN)
|
||||
trans.sa_session.add(role)
|
||||
# Create the UserRoleAssociations
|
||||
for user in [trans.sa_session.query(trans.app.model.User).get(x) for x in in_users]:
|
||||
ura = trans.app.model.UserRoleAssociation(user, role)
|
||||
trans.sa_session.add(ura)
|
||||
# Create the GroupRoleAssociations
|
||||
for group in [trans.sa_session.query(trans.app.model.Group).get(x) for x in in_groups]:
|
||||
gra = trans.app.model.GroupRoleAssociation(group, role)
|
||||
trans.sa_session.add(gra)
|
||||
if create_group_for_role_checked:
|
||||
# Create the group
|
||||
group = trans.app.model.Group(name=name)
|
||||
trans.sa_session.add(group)
|
||||
# Associate the group with the role
|
||||
gra = trans.model.GroupRoleAssociation(group, role)
|
||||
trans.sa_session.add(gra)
|
||||
num_in_groups = len(in_groups) + 1
|
||||
else:
|
||||
num_in_groups = len(in_groups)
|
||||
trans.sa_session.flush()
|
||||
role, num_in_groups = trans.app.security_agent.create_role(
|
||||
name, description, in_users, in_groups, create_group_for_role=create_group_for_role_checked)
|
||||
message = "Role '%s' has been created with %d associated users and %d associated groups. " \
|
||||
% (role.name, len(in_users), num_in_groups)
|
||||
if create_group_for_role_checked:
|
||||
|
||||
@@ -128,6 +128,30 @@ def inherit(context):
|
||||
</script>
|
||||
|
||||
<div id="registrationForm" class="toolForm">
|
||||
## only display the prepopulate form to admins
|
||||
%if show_user_prepopulate_form:
|
||||
<form name="registration" id="prepopulateform" action="${form_action}" method="post" >
|
||||
<input type="hidden" name="session_csrf_token" value="${trans.session_csrf_token}" />
|
||||
<div class="toolFormTitle">Pre-populate an account through LDAP</div>
|
||||
<div class="form-row">
|
||||
<label>Email address:</label>
|
||||
<input id="email_input" type="text" name="email" value="${email | h}" size="40"/>
|
||||
<input type="hidden" name="redirect" value="${redirect | h}" size="40"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Username:</label>
|
||||
<input id="name_input" type="text" name="username" size="40" value="${username |h}"/>
|
||||
<div class="toolParamHelp">
|
||||
Depending on your LDAP configuration in your auth_conf.xml you can either provide an
|
||||
email address or username.
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input type="submit" id="prepopulate" name="prepopulate_user_button" value="Prepopulate"/>
|
||||
</div>
|
||||
</form>
|
||||
<br />
|
||||
%endif
|
||||
<form name="registration" id="registration" action="${form_action}" method="post" >
|
||||
<input type="hidden" name="session_csrf_token" value="${trans.session_csrf_token}" />
|
||||
<div class="toolFormTitle">Create account</div>
|
||||
|
||||
Reference in New Issue
Block a user