Search for contributor with LDAP

I’ve just migrated a site from 1.2 to 2.1 and so far almost all is well.

We authenticate against our institutional LDAP server, and that works for logins.

But when trying to add a contributor to an event, the search option does not work.
In 1.2 there was a check box on the user search dialog specifying "search LDAP"
That function mostly worked. That is, it worked only for email addresses, and only for exact matches, but that was good enough.

In 2.0 the user search dialog no longer has a “search LDAP” check box. The only options are “Exact Match” and "users with no Indico account"
Any attempt to search for a user just hangs, with the rotating wait symbol. I can’t search against name or email address, partial or complete.

I can verify that these users exist by looking in the User management section. That search function works.

I’m supposing that my LDAP configuration must not be quite right, even though logins work fine.

I’m not sure how to diagnose the problem, since the search never completes there is no error report.

Here is my ldap configuration from indico.conf:

 _ldap_config = {
    'uri': 'ldaps://ourldapserver',
    'bind_dn': '',
    'bind_password': '',
    'timeout': 30,
    'verify_cert': True,
    'page_size': 1500,
    'user_base': 'ou=People,DC=lbl,DC=gov',
    'gid': 'cn',
    'group_base': 'OU=Groups, DC=lbl, DC=gov',
    'group_filter': '(objectClass=groupOfUniqueNames)',
    'member_of_attr': 'uniqueMember',
    'ad_group_style': True
}

AUTH_PROVIDERS = {
    'ldap': {
        'type': 'ldap',
        'title': 'LDAP',
        'ldap': _ldap_config,
        'default': True
    }
}

IDENTITY_PROVIDERS = {
    'ldap': {
        'type': 'ldap',
        'title': 'LDAP',
        'ldap': _ldap_config,
        'mapping': {
            'first_name': 'givenName',
            'last_name': 'sn',
            'email': 'mail',
        },
        'trusted_email': True,
        'default_group_provider': True,
         'synced_fields': {'first_name', 'last_name'}
    }
}

This is the same as the old “search in LDAP” option - we just renamed it because they don’t have to come from LDAP, someone could write a plugin that fetches user information from something else.

When testing, please enable “exact match” - doing a non-exact search can be very slow depending on how many users there are in your LDAP server. You can also test whether search in LDAP works or not on the command-line using the indico user search command. When using the --include-external switch it will search in LDAP as well.

Thanks for the pointers to the command line tool.

‘indico user search’ works fine, but the “Choose person” dialog that comes up when adding a contributor still never returns a result. I’ve enabled “exact match” and “users with no indico account” and get the same result.

I’ve enabled DEBUG in indico.conf, but it doesn’t produce any clues.

Interestingly, ‘indico user search’ only works for email addresses. When I try to search on last name, for example, I get this:

(.venv)[indico@indico ~]$ indico user search -s Anderson -X
Traceback (most recent call last):
  File "/opt/indico/.venv/bin/indico", line 11, in <module>
    sys.exit(cli())
  File "/opt/indico/.venv/lib/python2.7/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/opt/indico/.venv/lib/python2.7/site-packages/flask/cli.py", line 380, in main
    return AppGroup.main(self, *args, **kwargs)
  File "/opt/indico/.venv/lib/python2.7/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/opt/indico/.venv/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/opt/indico/.venv/lib/python2.7/site-packages/indico/cli/util.py", line 119, in invoke
    return self._impl.invoke(ctx)
  File "/opt/indico/.venv/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/opt/indico/.venv/lib/python2.7/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/opt/indico/.venv/lib/python2.7/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/opt/indico/.venv/lib/python2.7/site-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/opt/indico/.venv/lib/python2.7/site-packages/flask/cli.py", line 257, in decorator
    return __ctx.invoke(f, *args, **kwargs)
  File "/opt/indico/.venv/lib/python2.7/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/opt/indico/.venv/lib/python2.7/site-packages/indico/cli/user.py", line 76, in search
    external=include_external, allow_system_user=include_system, **criteria)
  File "/opt/indico/.venv/lib/python2.7/site-packages/indico/modules/users/util.py", line 239, in search_users
    for ident in identities:
  File "/opt/indico/.venv/lib/python2.7/site-packages/flask_multipass/core.py", line 347, in search_identities
    for identity_info in provider.search_identities(provider.map_search_criteria(criteria), exact=exact):
  File "/opt/indico/.venv/lib/python2.7/site-packages/flask_multipass/providers/ldap/providers.py", line 191, in search_identities
    yield IdentityInfo(self, identifier=user_data[self.ldap_settings['uid']][0], **to_unicode(user_data))
KeyError: 'uid'

Strange that uid is not present - it’s supposed to be set to the default value when not specified.
Try adding 'uid': 'cn' to your ldap config dict.

I thought that was strange as well. Our LDAP does provide ‘uid’, as confirmed by ldapsearch, and it is not equal to ‘cn’ But I will try making the change and see what happens.

Use 'uid': 'uid' in that case. That should be the default, but according to the error you get the entry is missing…

‘uid’: ‘uid’ did not work.

But somehow ‘uid’: ‘cn’ does work. Now the search dialog returns the correct results, even for partial searches, so much better than in the 1.2 days.

Thanks for your assistance.

I seem to have spoken too soon.

Setting ‘uid’: ‘cn’ makes searching work, but then logins are broken. It seems that the default mapping of ‘uid’: ‘uid’ was correct for logins with our particular LDAP server.

The search dialog from the webpage also works correctly now with ‘uid’: ‘uid’

But the command line tool is still broken when searching for names. It works for searching on email. I guess I can live with that.

uid should point to the attribute that’s a unique identifier for the user. Whether that’s CN, UID, or somehing else depends on your LDAP server. During login we use the value of that attribute to see who the Indico user corresponding to the LDAP data is; so if you change the attribute then people cannot login unless they have matching emails (email matching is always done as a fallback when there is no uid match)

Thanks. The function of the ldap attribute mapping in indico.conf is much clearer to me now and I understand why the logins stopped working.

I think I’m stable now. Our current situation is that internal searches all work, but external searches only work for email (just like in indico 1.2). Mapping ‘uid’ to something other than the default causes external searches against names to work, but that is clearly not an option for us since it breaks our login procedure. I would guess this is a bug somewhere in the search code, but it is not fatal for us. Mapping ‘uid’: ‘uid’ throws the unkown key error during searches as before., but only when searching on names. Strange.

That sounds very strange indeed… especially if you do get the correct names when registering in via LDAP. Usually searches by name etc. not working means the mapping between LDAP attributes and the fields in Indico (first/last name, etc.) isn’t correct.

That’s what I thought as well.

But simply mapping ‘uid’: ‘cn’ causes all searches to work properly. Of course that messes up logins because users aren’t expecting to have to use ‘cn’ as their username.