Skip to content

Instantly share code, notes, and snippets.

@0xjac
Created April 22, 2015 14:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save 0xjac/836e566c3b272fc55ac3 to your computer and use it in GitHub Desktop.
Save 0xjac/836e566c3b272fc55ac3 to your computer and use it in GitHub Desktop.
Flask-Multipass Instructions

Thank you for helping us test the new LDAP provider for Indico.

Below you will find instructions on how to install and use the example application for testing. While this is a very simple application, it uses the same code as Indico 2.0 to perform LDAP operations.

Testing this application with the LDAP server you use for Indico will allow us to catch LDAP related bugs before we release Indico 2.0 or Flask-Multipass.

Prerequisites

Flask-Multipass requires Python 2.7 or newer. You can test it using:

python --version

For the python-ldap library to work, you will also need to have the OpenLDAP client libraries version 2.4.11 or later, as well as OpenSSL if you connect to your LDAP server over SSL. (See the python-ldap prerequisites for more details.)

If you perform the installation on a machine which can run Indico with LDAP authentication, those libraries should already be present.

If you have an OpenLDAP server, make sure the member of attribute is enabled. You can do so with a simple ldapsearch for a user who is part of some groups.

If it is enabled you should see the member of attribute with the distinguished names of the groups he is a members of. If it is not enabled you can have a look here for instructions on how to enable it.

Installation

Follow these simple steps to install the example application and connect it with your LDAP server.

  1. Get Flask-Multipass from GitHub.
git clone https://github.com/indico/flask-multipass.git --branch indico-admins-test
  1. Create a new virtual environment.
cd flask-multipass
virtualenv env
source env/bin/activate

If the virtualenv command is not available, you can install it using

pip install virtualenv
  1. Install Flask-Multipass. (Don't forget the dot.)
pip install -e .
  1. Install the dependencies for the example application (this includes python-ldap).
pip install -r example/requirements.txt

You will need the OpenLDAP client libs version 2.4.11 or later
(see the python-ldap documentation on prerequisites).

  1. Download the example configuration into example/example.cfg:
    • Active Directory Server

      wget http://git.io/vfnvm -O example/example.cfg
    • OpenLDAP Server

      wget http://git.io/vfnvB -O example/example.cfg

      and adapt the file (example/example.cfg) to your LDAP server.

See the available LDAP Options for more details on how to configure the application. You must also configure the values of the mapping between application keys and the LDAP attributes on lines 35-38. (See the mapping section for more information.)

  1. Run the application. (It will be available at 127.0.0.1:10500.)
python example/example.py

LDAP Options

  • uristr (required, default: None)
    The URI referring to the LDAP server including the protocol and the port.
    Use ldaps:// for LDAP over SSL/TLS and ldap:// with the starttls option for a plain LDAP connection with TLS negotiation.
    The port can be omitted if the LDAP server listens on the default port (636 for LDAP over SSL and 389 for a plain LDAP connection with TLS negotiation).

  • bind_dnstr (required, default: None)
    The distinguished name to bind to the LDAP directory.

  • bind_passwordstr (required, default: None)
    The bind password for simple authentication

  • timeoutint (default: 30)
    The delay in seconds to wait for a reply from the LDAP server (-1 to disable).

  • verify_certbool (default: True)
    Whether to verify the server certificate or not.
    Equivalent to LDAP's TLS_REQCERT option where demand is True and allow is False. That is, True will require a certificate and fail if the certificate is missing or could not be validated. (This should be used in production.) False will accept a certificate but it will not fail if the certificate is missing or invalid.

  • starttlsbool (default: False)
    Whether to start TLS negotiation or not. (Ignored with a LDAP over SSL connection.)

  • page_sizeint (default: 1000)
    The limit of entries to retrieve at once for a search.
    0 means no size limit. It is recommended to have at most the size limit set by the server.

  • uidstr (default: 'uid')
    The attribute whose value is used as an identifier for the user (typically the username).
    This attribute must be a single-valued attribute whose value is unique for each user. If the attribute is multi-valued, only the first one retrieved will be returned.

  • user_basestr (required, default: None)
    The base node for all the nodes which might contain a user.

  • user_filterstr (default: '(objectClass=person)')
    A valid LDAP filter which will select exclusively all users in the subtree from the user_base. The combination of the user_base and the user_filter must match exclusively all the users.

  • gidstr (default: 'cn')
    The attribute whose value is used as an identifier for the group (typically the group's name).
    This attribute must be a single-valued attribute whose value is unique for each group. If the attribute is multi-valued, only the first one retrieved will be returned.

  • group_basestr (required, default: None)
    The base node for all the nodes which might contain a group.

  • group_filterstr (default: '(objectClass=groupOfNames)')
    A valid LDAP filter which will select exclusively all groups in the subtree from the group_base. The combination of the group_base and the group_filter must match exclusively all the groups.

  • member_of_attrstr (default: 'memberOf')
    The multi-valued attribute of a user containing the list of groups a user is a member of.

    The member of must be enabled on SLAPD servers. While it is not by default, the majority of servers will have it enabled. A simple ldapsearch for a user member of any group should show if that is the case. (See this article on how to enable MemberOf with OpenLDAP for more details if it is not.)

  • ad_group_stylebool (default: False)
    Whether the server uses Active Directory group style or not.
    This is only use to check if a user is a member of a group. In the case of Active Directory, it will take advantage of the tokenGroups attribute of a user to check for nested group membership. Otherwise, it will only look through the values of the member of attribute, which should also work for Active Directory, but only for direct membership.

Mapping

The mapping allows to map the attributes of an LDAP entry to the application keys and is defined in example.cfg. The example application expects 3 keys (defined in MULTIPASS_IDENTITY_INFO_KEYS, line 49): email, name and affiliation. The corresponding attributes could be for example: mail, givenName and org. If a key is missing from the mapping, it is assumed that the application key and LDAP attribute are identical.

Note: While this simple application only uses the first name. Indico will have more applications keys, including the last name, the phone number and the address of a user.

Using and testing the application

Once the application is running you can access it via your web browser at: 127.0.0.1:10500. Here are a few scenarios you can try to make sure, the application works with your LDAP server and that the configuration is correct:

Authentication

  1. Click on Log in at the top left of the screen.
  2. Make sure it says "Log in using My Organization LDAP" and log in.
  3. At the top of the page you should see a line starting with
    success: Received IdentityInfo: <IdentityInfo(<LDAPIdentityProvider(my-ldap)>
    

followed by your user information.

User Search

  1. Search for a user by his name and/or email. By default this will be a wildcard match, tick Exact for an exact match, try both.
  2. Check the results are consistent with your LDAP data.

Group Search and Membership

  1. Search a group by name (wildcard and exact match)
  2. Check the results are consistent.
  3. Click on a group in the search results and check the list of members is correct.
  4. While logged in:
    1. Search for a group you are a member of.
    2. Go to the list of members by clicking on the group.
    3. At the bottom of the list of members. Make sure it says: You are a group member: YES
    4. Repeat the steps above for a group you are not a member of and check that it says: You are a group member: NO at the bottom the of list of members.
@hger
Copy link

hger commented Apr 24, 2015

We have an Active Directory setup and everything works well with one exception:
The name of the user is mapped to givenName but in our setup the whole name is mapped to displayName or cn. If I could set this mapping for users all would be well.
This new method also solves an old issue we have had with our users being spread out into many separate OUs in the tree, now all users can log in. Please add the possibility to map userdisplay name to an attribute and all is well for us.
Thank you

/Håkan

@ThiefMaster
Copy link

In the example app, you can simply replace 'name': 'givenName' with 'name': 'displayName' to get the full name.

In Indico itself we have two fields (first_name and last_name) so you'd map whatever fields in LDAP provide those names.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment