LDAP login 500 Internal Server Error if mail addresses are colliding

Issue #124 new
Alexey Vasiliev created an issue

Ldap module configured to connect to AD ldap port 3268 (objectClass=*).
Login attribute sAMAccountName Subtree
email attribyte in AD is mail.
If that attribute filled in config Email Attribute : mail
all LDAP users with mail address cannot login to kallithea with error 500 (users who don't have email still can login)

Please find below the error in log:

2015-04-15 18:45:18.245 INFO  [kallithea.lib.auth_modules] Authenticating user using kallithea.lib.auth_modules.auth_ldap plugin
2015-04-15 18:45:18.408 INFO  [kallithea.lib.auth_modules.auth_ldap] user alexey authenticated correctly
Error - <class 'sqlalchemy.exc.IntegrityError'>: (IntegrityError) UNIQUE constraint failed: users.email u'UPDATE users SET password=?, email=? WHERE users.user_id = ?' ('$2a$10$fJ.JA4IemdQLsJsOzKqDvOItcr4tJ1D6JQSA0c4FLg/6JecFThVXu', 'alexey.vasiliev@company.com', 3)
URL: http://kallithea:5000/_admin/login?came_from=%2F
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/weberror/errormiddleware.py', line 162 in __call__
  app_iter = self.application(environ, sr_checker)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/beaker/middleware.py', line 155 in __call__
  return self.wrap_app(environ, session_start_response)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/routes/middleware.py', line 131 in __call__
  response = self.app(environ, start_response)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/pylons/wsgiapp.py', line 107 in __call__
  response = self.dispatch(controller, environ, start_response)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/pylons/wsgiapp.py', line 312 in dispatch
  return controller(environ, start_response)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/kallithea/lib/base.py', line 383 in __call__
  return WSGIController.__call__(self, environ, start_response)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/pylons/controllers/core.py', line 211 in __call__
  response = self._dispatch_call()
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/pylons/controllers/core.py', line 162 in _dispatch_call
  response = self._inspect_call(func)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/pylons/controllers/core.py', line 105 in _inspect_call
  result = self._perform_call(func, args)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/pylons/controllers/core.py', line 57 in _perform_call
  return func(**args)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/kallithea/controllers/login.py', line 122 in index
  c.form_result = login_form.to_python(dict(request.POST))
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/formencode/api.py', line 439 in to_python
  value = tp(value, state)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/formencode/schema.py', line 226 in _to_python
  new = validator.to_python(new, state)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/formencode/api.py', line 442 in to_python
  vp(value, state)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/kallithea/model/validators.py', line 319 in validate_python
  if not auth_modules.authenticate(username, password):
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/kallithea/lib/auth_modules/__init__.py', line 408 in authenticate
  environ=environ or {})
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/kallithea/lib/auth_modules/__init__.py', line 293 in _authenticate
  Session().flush()
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py', line 1734 in flush
  self._flush(objects)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py', line 1805 in _flush
  flush_context.execute()
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.py', line 331 in execute
  rec.execute(self)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.py', line 475 in execute
  uow
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/persistence.py', line 59 in save_obj
  mapper, table, update)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/persistence.py', line 485 in _emit_update_statements
  execute(statement, params)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py', line 1449 in execute
  params)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py', line 1584 in _execute_clauseelement
  compiled_sql, distilled_params
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py', line 1698 in _execute_context
  context)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py', line 1691 in _execute_context
  context)
File '/opt/kallithea/venv/local/lib/python2.7/site-packages/sqlalchemy/engine/default.py', line 331 in do_execute
  cursor.execute(statement, parameters)
IntegrityError: (IntegrityError) UNIQUE constraint failed: users.email u'UPDATE users SET password=?, email=? WHERE users.user_id = ?' ('$2a$10$fJ.JA4IemdQLsJsOzKqDvOItcr4tJ1D6JQSA0c4FLg/6JecFThVXu', 'alexey.vasiliev@company.com', 3)


CGI Variables
-------------
  CONTENT_TYPE: 'application/x-www-form-urlencoded; charset="utf-8"'
  HTTP_ACCEPT: 'text/html, text/*;q=0.9, image/jpeg;q=0.9, image/png;q=0.9, image/*;q=0.9, */*;q=0.8'
  HTTP_ACCEPT_CHARSET: 'utf-8,*;q=0.5'
  HTTP_ACCEPT_ENCODING: 'gzip, deflate, x-gzip, x-deflate'
  HTTP_ACCEPT_LANGUAGE: 'ru,en-US;q=0.9,en;q=0.8'
  HTTP_CACHE_CONTROL: 'no-cache'
  HTTP_CONNECTION: 'keep-alive'
  HTTP_COOKIE: 'kallithea=9e28e83b95427ef79085741f73bf009c3280713e2d08fc1812ab4cbd9060e0238607feda'
  HTTP_HOST: 'kallithea:5000'
  HTTP_PRAGMA: 'no-cache'
  HTTP_REFERER: 'http://kallithea:5000/'
  HTTP_USER_AGENT: 'Mozilla/5.0 (X11; Linux x86_64) KHTML/4.14.3 (like Gecko) Konqueror/4.14'
  PATH_INFO: '/_admin/login'
  QUERY_STRING: 'came_from=%2F'
  REMOTE_ADDR: '192.168.1.1'
  REQUEST_METHOD: 'POST'
  SERVER_NAME: 'localhost'
  SERVER_PORT: '5000'
  SERVER_PROTOCOL: 'HTTP/1.1'
  SERVER_SOFTWARE: 'waitress'


WSGI Variables
--------------
  application: <beaker.middleware.SessionMiddleware object at 0x7f175589d550>
  beaker.get_session: <bound method SessionMiddleware._get_session of <beaker.middleware.SessionMiddleware object at 0x7f175589d550>>
  beaker.session: {'_accessed_time': 1429112718.181142, '_creation_time': 1429112718.181142}
  paste.parsed_querystring: ([('came_from', '/')], 'came_from=%2F')
  paste.registry: <paste.registry.Registry object at 0x7f174eb5ead0>
  paste.throw_errors: True
  pylons.action_method: <bound method LoginController.index of <kallithea.controllers.login.LoginController object at 0x7f174ecfca10>>
  pylons.controller: <kallithea.controllers.login.LoginController object at 0x7f174ecfca10>
  pylons.environ_config: {'session': 'beaker.session', 'cache': 'beaker.cache'}
  pylons.pylons: <pylons.util.PylonsContext object at 0x7f174ecfcfd0>
  pylons.routes_dict: {'action': u'index', 'controller': u'login'}
  routes.route: <routes.route.Route object at 0x7f1755f44390>
  routes.url: <routes.util.URLGenerator object at 0x7f174ec63ed0>
  webob._parsed_post_vars: (MultiDict([('_authentication_token', '130779523276473337233051272781982439844'), ('username', 'alexey'), ('password', '******'), ('sign_in', 'Log In')]), <FakeCGIBody at 0x7f174ec63750 viewing MultiDict([('_a...n')])>)
  webob._parsed_query_vars: (GET([('came_from', '/')]), 'came_from=%2F')
  webob.adhoc_attrs: {'errors': 'ignore', 'user': <AuthUser('id:1[default] ip:192.168.1.1 auth:True')>, 'language': 'en-us'}
  webob.is_body_readable: True
  webob.is_body_seekable: False
  wsgi process: 'Multithreaded'
  wsgi.file_wrapper: <class 'waitress.buffers.ReadOnlyFileBasedBuffer'>
  wsgiorg.routing_args: (<routes.util.URLGenerator object at 0x7f174ec63ed0>, {'action': u'index', 'controller': u'login'})
------------------------------------------------------------

Comments (7)

  1. JF

    I remember running into this because LDAP was returning an email address that was ALREADY in the database. In its user model, it appears Kallithea requires email addresses to be unique.

    Hope that helps,

    JF

  2. Thomas De Schampheleire

    @robinton Was this problem indeed caused by e-mail address clashes with existing users?

    @kwi @kiilerix Any input here? I suppose we could/should detect such collision gracefully? Is it perhaps already fixed with the recent Auth changes by @kwi?

  3. Mads Kiilerich

    I guess we could check if the authentication is changing the email address ... and if so, check if another user is using that address and deny the login with a helpful message.

  4. Søren Løvborg

    My auth changes doesn't touch this (not intentionally, at least). This problem follows from uniquely identifying users both by username and by email address. Solutions: 1) allow different users to have the same email (eek), 2) allow one user to have multiple usernames (yikes), 3) turn error 500 into a more reasonable error message. I'll go out on a limb and suggest #3 as well. ;-)

  5. Scott Palmer

    This should show a more useful error message. I got this because I used my email address for the admin user, then I also wanted to log in with my normal username. I had to look at the logs/error email to see what actually happened, but the web UI should have told me. (I worked around it using a different alias for my email with the admin user.)

  6. Log in to comment