Giter Club home page Giter Club logo

flask-multipass's Introduction

Indico CI Status License Available on PyPI Made at CERN!

Indico is:

  • πŸ—“ a general-purpose event management tool;
  • 🌍 fully web-based;
  • 🧩 feature-rich but also extensible through the use of plugins;
  • βš–οΈ Open-Source Software under the MIT License;
  • made at CERN, the place where the web was born!

A sneak peek of Indico

What does it do?

Indico's main features are:

  • a powerful and flexible hierarchical content management system for events;
  • a full-blown conference organization workflow with:
    • πŸ“’ Call for Abstracts and abstract reviewing modules;
    • πŸ“ flexible registration form creation and configuration;
    • πŸ’° integration with existing payment systems;
    • βœ… a paper reviewing workflow;
    • πŸ—“ a drag and drop timetable management interface;
    • 🎫 a simple badge editor with the possibility to print badges and tickets for participants;
  • tools for meeting management and archival of presentation materials;
  • a powerful room booking interface;
  • integration with existing video conferencing solutions;

A more detailed list can be found here. There is also a video!

I just want to try it out!

We've got a SandboxπŸ§ͺ!

Browser support

These are the minimum versions of major browsers currently supported by Indico. We try to target all modern browsers as much as possible, but only issues detected on those will be considered at critical level.

Firefox
Firefox
Chrome
Chrome
Safari
Safari
Edge
Edge
78+ 83+ 13+ 17+

However, if you have an issue with a browser on this list, please feel free to open a bug report.

Getting Indico

Information on how to get the latest release can be found at the project's web site. There are installation guides for different systems available in the project's documentation.

Contributing

Indico is the result of the collective work of more than 100 different developers, translators and usability specialists of many nationalities. You can be the next one - read our Contribution Guide if you'd like to help out.

You don't need to know how to write code in order to help!

Roadmap

The full roadmap is available on the project site.

Community

The main meeting points for the community are:

We follow CERN's Values and the principles established by CERN's Code of Conduct.

History

This software project was initially funded by the European Union's FP5 programmeπŸ‡ͺπŸ‡Ί, in what was called the Integrated Digital Conferencing Project, or just InDiCo. CERN was responsible for the development of the "Make-a-Confererence" workpackage (inspired by an already existing system called CDS Agenda, also developed at the Organization) which would then become what we nowadays know as Indico.

We have since stopped using the InDiCo acronym, as it no longer reflects accurately the nature of the project. The word Indico now has no particular meaning other than the product's name.


Made at CERN
Take part!

Note

In applying the MIT license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction.

flask-multipass's People

Contributors

arrdem avatar bartoldu avatar cbartz avatar davidandreev avatar dependabot[bot] avatar jouvin avatar kastanas avatar lucaswiman avatar nop33 avatar omegak avatar pferreir avatar thiefmaster avatar tschoonj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flask-multipass's Issues

Properly document oauth-related changes in 0.3

Ideally also explain roughly how to update from the old oauth config to the new one.
Let's not repeat stuff already documented in the authlib docs though, better link there.

And make sure we don't have any broken links left, like the one in the README to oauth.py.

Send `id_token_hint` with OIDC logout

OIDC logout requests have an id_token_hint parameter. This parameter is not required, but recommended by spec and some providers may not be able to properly terminate a user session if that parameter is missing. They then just delete the cookies, but not end the session. (see below) It would be nice if this parameter could be added. This should be the right place:

query = url_encode({'post_logout_redirect_uri': return_url})

Allow collections to be specified in search

multiauth.search_identities(email='[email protected]')
multiauth.search_identities(email={'[email protected]', '[email protected]'})

the items in the collection would be used OR-style, so the second line in the example above would find identities which have any of those emails.

I'd suggest to check for isinstance(value, (tuple, list, set)). That way we don't lose the ability to search e.g. for a bool or number in case there's a provider using such types.

Question: decorator to check login?

Hi,
is there a decorator to check if a user is logged in before returning a view? I found multipass.login_check() but I`m not quite sure how to use it as documentation is a bit thin on it.
Any Help would be appreciated, I'd help improve the documentation, if I would know how to to this.

Roadmap question: dropping Python 2.X

As Python 2.X is solidly end of lifed at this point, at what point do y'all intend for Multipass to go py3k only? Or is maintaining py2k capability something y'all desire?

No opinion either way, Multipass works great on py3k, I just don't want to put up py3k only PRs if that isn't consistent with the roadmap.

Thanks!

Error in LDAP connection in "providers/ldap/util.py"

In a new installation of Newdle, which uses Flask Multipass as an authentication backend, I observe the following error in the app when trying to connect to a OpenLDAP server in "providers/ldap/util.py":

[2022-07-15 16:34:51,965] ERROR in app: Request failed
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 1523, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 1509, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/usr/local/lib/python3.10/site-packages/webargs/core.py", line 452, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/newdle/api.py", line 228, in users
    total, data = search_users(name, email, 10)
  File "/usr/local/lib/python3.10/site-packages/newdle/core/auth.py", line 59, in search_users
    identities, total = multipass.search_identities_ex(
  File "/usr/local/lib/python3.10/site-packages/flask_multipass/core.py", line 399, in search_identities_ex
    result = list(itertools.islice(result_iter, limit))
  File "/usr/local/lib/python3.10/site-packages/flask_multipass/providers/ldap/providers.py", line 194, in search_identities
    with ldap_context(self.ldap_settings):
  File "/usr/local/lib/python3.10/contextlib.py", line 135, in __enter__
    return next(self.gen)
  File "/usr/local/lib/python3.10/site-packages/flask_multipass/providers/ldap/util.py", line 68, in ldap_context
    connection = ldap_connect(settings, use_cache=use_cache)
  File "/usr/local/lib/python3.10/site-packages/flask_multipass/providers/ldap/util.py", line 138, in ldap_connect
    ldap_connection.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND if use_ldaps else ldap.OPT_X_TLS_NEVER)
AttributeError: module 'ldap' has no attribute 'OPT_X_TLS'

I have traced the error to using the latest version of python-ldap, version 3.4.2 (release 2022-07-06), which removes the deprecated option OPT_X_TLS, see the changelog.

Explicitly requiring at most python-ldap-3.4.1 makes everything work again.

Type error on init_app

File ".../site-packages/flask_multipass/util.py", line 146, in resolve_provider_type
entry_points = importlib_entry_points(group=base._entry_point, name=type_)

TypeError: entry_points() for an unexpected keyword argument 'group'

I see this error and version 0.5 dies while loading.
It's trying to call importlib.metadata.entrypoints but that doesn't have a group argument.

SP not at server root

Hi, All. First I would like to say thank you for all the work that went into this. I am trying to get this working with SAML as a first step before approaching my campus SSO managers, but I am hitting a dead end. After some head scratching and some research, I think I have come to the conclusion that either flask-multipass or one of its dependencies assumes that the flask site will be at the root of the server rather than a subdirectory as it is in my case. Eventually I get the following error message after logging in at the IDP- "Authentication failed: SAML login failed (The response was received at https://jb-serv.fullerton.edu/multipass/saml/saml/acs instead of https://jb-serv.fullerton.edu/escapeRoom/multipass/saml/saml/acs)". It may be related to this validation check referenced here: SAML-Toolkits/python3-saml#83
As a consequence of all this, I have a few questions.

  1. Is my assumption correct and without a feature enhancement, there would be no way for it to be configured to work for a site that is not served directly off the root?
  2. If, my assumption is incorrect, what changes to the configuration do I need to make to eliminate the error I am seeing?
  3. If someone has a working configuration that does SAML for a flask site not served from root, would they be willing to share it minus any sensitive data of course?

Thanks you for your time,

Dave

A couple of items that may help with helping me:

Here is my metadata link if that helps: https://jb-serv.fullerton.edu/escapeRoom/multipass/saml/saml/metadata

This is my saml config dictionary minus the certs for my SP.

_my_saml_config = {
    # If enabled, errors are more verbose and received attributes are
    # printed to stdout
    'debug': True,
    'sp': {
        # this needs to match what you use when registering the SAML SP
        'entityId': 'https://jb-serv.fullerton.edu/escapeRoom',
        # these bindings usually do not need to be set manually; the URLs
        # are auto-generated
        # 'assertionConsumerService': {'binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'},
        # 'singleLogoutService': {'binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'},
        # depending on your security config you may need to generate a
        # certificate and private key.
        # you can use https://www.samltool.com/self_signed_certs.php or
        # use `openssl` for it (which is more secure as it ensures the
        # key never leaves your machine)
        'x509cert': '''redacted''',
        'privateKey': '''redacted''',
        # persistent name ids are the default, but you can override it
        # with a custom format
        # 'NameIDFormat': 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
    },
    'idp': {
        # This metadata is provided by your SAML IdP. You can omit (or
        # leave empty) the whole 'idp' section in case you need SP
        # metadata to register your app and get the IdP metadata from
        # https://yourapp.example.com/multipass/saml/{auth-provider-name}/metadata
        # and then fill in the IdP metadata afterwards.
        'entityId': 'https://samltest.id/saml/idp',
        'x509cert': '''MIIDETCCAfmgAwIBAgIUZRpDhkNKl5eWtJqk0Bu1BgTTargwDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAwwLc2FtbHRlc3QuaWQwHhcNMTgwODI0MjExNDEwWhcNMzgw
ODI0MjExNDEwWjAWMRQwEgYDVQQDDAtzYW1sdGVzdC5pZDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAJrh9/PcDsiv3UeL8Iv9rf4WfLPxuOm9W6aCntEA
8l6c1LQ1Zyrz+Xa/40ZgP29ENf3oKKbPCzDcc6zooHMji2fBmgXp6Li3fQUzu7yd
+nIC2teejijVtrNLjn1WUTwmqjLtuzrKC/ePoZyIRjpoUxyEMJopAd4dJmAcCq/K
k2eYX9GYRlqvIjLFoGNgy2R4dWwAKwljyh6pdnPUgyO/WjRDrqUBRFrLQJorR2kD
c4seZUbmpZZfp4MjmWMDgyGM1ZnR0XvNLtYeWAyt0KkSvFoOMjZUeVK/4xR74F8e
8ToPqLmZEg9ZUx+4z2KjVK00LpdRkH9Uxhh03RQ0FabHW6UCAwEAAaNXMFUwHQYD
VR0OBBYEFJDbe6uSmYQScxpVJhmt7PsCG4IeMDQGA1UdEQQtMCuCC3NhbWx0ZXN0
LmlkhhxodHRwczovL3NhbWx0ZXN0LmlkL3NhbWwvaWRwMA0GCSqGSIb3DQEBCwUA
A4IBAQBNcF3zkw/g51q26uxgyuy4gQwnSr01Mhvix3Dj/Gak4tc4XwvxUdLQq+jC
cxr2Pie96klWhY/v/JiHDU2FJo9/VWxmc/YOk83whvNd7mWaNMUsX3xGv6AlZtCO
L3JhCpHjiN+kBcMgS5jrtGgV1Lz3/1zpGxykdvS0B4sPnFOcaCwHe2B9SOCWbDAN
JXpTjz1DmJO4ImyWPJpN1xsYKtm67Pefxmn0ax0uE2uuzq25h0xbTkqIQgJzyoE/
DPkBFK1vDkMfAW11dQ0BXatEnW7Gtkc0lh2/PIbHWj4AzxYMyBf5Gy6HSVOftwjC
voQR2qr2xJBixsg+MIORKtmKHLfU''',
        'singleSignOnService': {
            'url': 'https://samltest.id/idp/profile/SAML2/Redirect/SSO',
            'binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
        },
        # If you do not want to perform a SAML logout when logging out
        # from your application, you can omit this section
        'singleLogoutService': {
            'url': 'https://samltest.id/idp/profile/SAML2/Redirect/SLO',
            'binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
        }
    },
    # These advanced settings allow you to tune the SAML security options.
    # Please see the documentation on https://github.com/onelogin/python3-saml
    # for details on how they behave. Note that by requiring signatures,
    # you usually need to set a cert and key on your SP config, but for
    # testing you may want to disable all signing-related options.
    'security': {
        'nameIdEncrypted': False,
        'authnRequestsSigned': False,
        'logoutRequestSigned': False,
        'logoutResponseSigned': False,
        'signMetadata': False,
        'wantMessagesSigned': False,
        'wantAssertionsSigned': False,
        'wantNameId' : True,
        'wantNameIdEncrypted': False,
        'wantAssertionsEncrypted': False,
        'allowSingleLabelDomains': False,
        'signatureAlgorithm': 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
        'digestAlgorithm': 'http://www.w3.org/2001/04/xmlenc#sha256'
    },
    # You can set contact information which will be included in the SP
    # metadata; it is up to the IdP if/how this information is used:
    # 'contactPerson': {
    #     'technical': {
    #         'givenName': 'technical_name',
    #         'emailAddress': '[email protected]'
    #     },
    #     'support': {
    #         'givenName': 'support_name',
    #         'emailAddress': '[email protected]'
    #     }
    # },
    # 'organization': {
    #     'en-US': {
    #         'name': 'sp_test',
    #         'displayname': 'SP test',
    #         'url': 'http://sp.example.com'
    #     }
    # }
}

Flask-multipass ldap incompatible with python-ldap >=3.4.0

The OPT_X_TLS flag has been deprecated in python-ldap 3.3.0 and removed in 3.4

2022-08-24 08:42:40,516 c21a2717f2244ef0 - indico.flask - ERROR errors.py:98 -- module 'ldap' has no attribute 'OPT_X_TLS'

Traceback (most recent call last):
File "/opt/indico/.venv/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request
rv = self.dispatch_request()
File "/opt/indico/.venv/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/opt/indico/.venv/lib/python3.9/site-packages/indico/web/flask/util.py", line 79, in wrapper
return obj().process()
File "/opt/indico/.venv/lib/python3.9/site-packages/indico/web/rh.py", line 281, in process
res = self._do_process()
File "/opt/indico/.venv/lib/python3.9/site-packages/indico/web/rh.py", line 252, in _do_process
rv = self._process()
File "/opt/indico/.venv/lib/python3.9/site-packages/indico/modules/auth/controllers.py", line 94, in _process
response = multipass.handle_login_form(provider, form.data)
File "/opt/indico/.venv/lib/python3.9/site-packages/flask_multipass/core.py", line 517, in handle_login_form
response = provider.process_local_login(data)
File "/opt/indico/.venv/lib/python3.9/site-packages/flask_multipass/providers/ldap/providers.py", line 71, in process_local_login
with ldap_context(self.ldap_settings, use_cache=False):
File "/usr/local/lib/python3.9/contextlib.py", line 119, in enter
return next(self.gen)
File "/opt/indico/.venv/lib/python3.9/site-packages/flask_multipass/providers/ldap/util.py", line 68, in ldap_context
connection = ldap_connect(settings, use_cache=use_cache)
File "/opt/indico/.venv/lib/python3.9/site-packages/flask_multipass/providers/ldap/util.py", line 138, in ldap_connect
ldap_connection.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND if use_ldaps else ldap.OPT_X_TLS_NEVER)
AttributeError: module 'ldap' has no attribute 'OPT_X_TLS'

OpenID Connect support?

Hi there,

We're planning on using Indico in combination with an OAuth2 server we've implemented on top of Osin. Today I noticed that this library does not yet implement OpenID Connect; it always calls into the UserInfo endpoint to obtain the user's identity, regardless of whether the OAuth2 service returns an ID Token. Our service didn't implement the UserInfo endpoint yet, so I just went ahead and added that. We'll likely need it for some other web applications as well.

Question: are you folks planning on adding OpenID Connect support to this library? This would effectively make the endpoint, identifier_field and mapping configuration options unnecessary for those providers.

`Unexpected Exception occurred at X: 'group_base'`

One user is now actively using our Indico installation based on

$ git log --no-decorate --oneline -1
c6b5a3042a Fix showing nonbookable period outside admin UI

Just now, the logger sent the log below:

Unexpected Exception occurred at platsch.molgen.mpg.de: 'group_base'

2022-06-30 18:10:35,693  cddddabd26354a15  2       indico.flask - ERROR errors.py:110 -- 'group_base'

Traceback (most recent call last):
  File "/project/indico/home/.local/lib/python3.9/site-packages/flask/app.py", line 1523, in full_dispatch_request
    rv = self.dispatch_request()
  File "/project/indico/home/.local/lib/python3.9/site-packages/flask/app.py", line 1509, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/project/indico/home/.local/lib/python3.9/site-packages/indico/web/flask/util.py", line 79, in wrapper
    return obj().process()
  File "/project/indico/home/.local/lib/python3.9/site-packages/indico/web/rh.py", line 281, in process
    res = self._do_process()
  File "/project/indico/home/.local/lib/python3.9/site-packages/indico/web/rh.py", line 252, in _do_process
    rv = self._process()
  File "/project/indico/home/.local/lib/python3.9/site-packages/webargs/core.py", line 452, in wrapper
    return func(*args, **kwargs)
  File "/project/indico/home/.local/lib/python3.9/site-packages/indico/modules/groups/controllers.py", line 158, in _process
    groups = GroupProxy.search(name, exact=exact)
  File "/project/indico/home/.local/lib/python3.9/site-packages/indico/modules/groups/core.py", line 115, in search
    result |= {GroupProxy(g.name, g.provider.name, _group=g)
  File "/project/indico/home/.local/lib/python3.9/site-packages/indico/modules/groups/core.py", line 115, in <setcomp>
    result |= {GroupProxy(g.name, g.provider.name, _group=g)
  File "/project/indico/home/.local/lib/python3.9/site-packages/flask_multipass/core.py", line 437, in search_groups
    yield from provider.search_groups(name, exact=exact)
  File "/project/indico/home/.local/lib/python3.9/site-packages/flask_multipass/providers/ldap/providers.py", line 232, in search_groups
    for group_dn, group_data in self._search_groups(search_filter):
  File "/project/indico/home/.local/lib/python3.9/site-packages/flask_multipass/providers/ldap/providers.py", line 182, in _search_groups
    return search(self.ldap_settings['group_base'], search_filter, attributes=[self.ldap_settings['gid']])
KeyError: 'group_base'

{'data': {'get': {'name': 'Organisators'},
          'headers': {'Accept': 'application/json, text/plain, */*',
                      'Accept-Encoding': 'gzip, deflate, br',
                      'Accept-Language': 'fr-FR,fr;q=0.9',
                      'Cookie': 'XXX',
                      'Host': 'events.molgen.mpg.de',
                      'Referer': 'https://events.molgen.mpg.de/event/1/manage/protection',
                      'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X '
                                    '10_15_7) AppleWebKit/605.1.15 (KHTML, '
                                    'like Gecko) Version/15.5 Safari/605.1.15',
                      'X-Csrf-Token': '93165c3d-f87f-4e44-8215-66dfab63006e',
                      'X-Requested-With': 'XMLHttpRequest'},
          'json': None,
          'post': {},
          'url': {}},
 'endpoint': 'groups.group_search',
 'id': 'cddddabd26354a15',
 'ip': 'XXX'
 'method': 'GET',
 'referrer': 'https://events.molgen.mpg.de/event/1/manage/protection',
 'rh': 'RHGroupSearch',
 'time': '2022-06-30T18:10:35.819807',
 'url': 'https://events.molgen.mpg.de/groups/api/search?name=Organisators',
 'user': {'email': '[[email protected]](mailto:[email protected])',
          'id': 2,
          'name': 'XXX'},
 'user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) '
               'AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 '
               'Safari/605.1.15'}

We do not maintain a group field in LDAP, and configured it like below:

LOCAL_IDENTITIES = False

_ldap_config = {
    'uri': 'ldaps://ldap.molgen.mpg.de',
    'bind_dn': 'cn=indico,dc=ldap,dc=apps,dc=molgen,dc=mpg,dc=DE',
    'bind_password': 'X',
    'timeout': 30,
    'verify_cert': True,
    'page_size': 1500,

    'uid': 'uid',
    'user_base': 'dc=user,dc=apps,dc=molgen,dc=mpg,dc=de',
    'user_filter': '(objectClass=molgenUser)',
}

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,
        'synced_fields': {'first_name', 'last_name'}
    }
}

trying example, but can't find sqlalchemy provider

hi

playing with the example.
There is only 3 providers in http://0.0.0.0:10500/login/

Available login providers:
    GitHub
    Insecure dummy auth
    SSO

but where is the provider "example_local" which is in the code?

from flask_multipass.providers.sqlalchemy import SQLAlchemyAuthProviderBase, SQLAlchemyIdentityProviderBase

multipass.register_provider(LocalAuthProvider, 'example_local')
multipass.register_provider(LocalIdentityProvider, 'example_local')

Mail attribute from IdP is delivered as List of Addresses

Problem Description
During the authentication procedure against our identity provider using the shibboleth method, one gets back a list of attributes including among others like Eppn, Cn, Givenname, Sn the attribute Mail. In our IdP case this is not a single email address, but a list of the primary address followed by an arbitrary list of aliases. This looks e.g. like:

Mail = '[email protected];[email protected];[email protected]; ...'

Or given in the full context (as example):

{u'data': {u'get': {},
           u'headers': {'Accept': u'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                        'Accept-Encoding': u'gzip, deflate, br',
                        'Accept-Language': u'de,en;q=0.8,fr;q=0.5,en-US;q=0.3',
...
                        'Host': u'indico-site.example.org',
                        'Mail': u'[email protected];[email protected];[email protected]',
                        'O': u'some-organisation',
                        'Ou': u'',
...                        

It seems, that indico requires a single email address at this point, as the data set shown upon login is the full string of all emails. This does not allow the Mail field to be used in the user data set in indico.

Solution Proposal
It seems this problem could be solved by adding some parameters to the indico.conf syntax. One parameter covering the field separator and another one indicating which one of the fields should be taken as email address.

An indico.conf could for example look like the following:

IDENTITY_PROVIDERS = {
...
        'our-location-sso': {
        'type': 'shibboleth',
        'title': 'Shibboleth User Login)',
        'identifier_field': 'eppn',
# proposed new parameters:        
        'mail_array': True,
        'mail_separator': ';',
        'mail_index': 0,
# end of new parameters        
        'mapping': {
            'first_name': 'givenName',
            'uid': 'eppn', 
            'last_name': 'sn',
            'Sn': 'sn',
            'mail' : 'eppn',
...            
        }
}
...

This is my proposal. The example has three new parameters. mail_array defaulting to False, so that current configs will not get broken for backward compatibility, mail_separator containing the field separator of the string and mail_index providing the index in the mail array that provides the email address to be chosen by indico.

LDAP identity provider ignore the uid parameter

The Indico documentation states that it is possible to define the attribute to use as the UID in the LDAP identity providder, using the uid parameter. Unfortunately this doesn't work because this parameter is not read by the provider but is set inconditionnaly to uid in the constructor of the LDAPProviderMixin class.

Add pretty identifier

Identity.identifier, while being the uid in the identity provider it is also quite meaningless when displayed to users (i.e. For Github, it is a numeric id instead of the username). We should have a way to specify which data field of the identity from a provider is the one relevant to the user. Something along this line would be a first approach to tackle it.

@property
def pretty_identifier(self):
    return self.data[provider_settings['pretty_identifier']] if provider_settings['pretty_identifier'] else self.identifier
IdentityProviders = {
    'github': {
        'type': 'oauth',
        'title': 'GitHub',
        'oauth': _github_oauth_config,
        'identifier_field': 'id',
        'pretty_identifier': 'username',
    },

Add signals

There should be some signals for events like "authentication failed" and "authentication successful".

This would make it easy for an application to log those events (or forward them to systems such as fail2ban).

Support SAML groups via attribute

In the SAML provider, it would be great if Groups were implemented. IIUC, there could be code in the saml identity provider that reads a group membership from the SAML attributes, and the IDP/SP need to be configured to pass on that group membership.

LDAP search doesn't work with unicode strings

Search e.g. for a last name containing an ΓΆ:

  File "/home/adrian/dev/flask-multipass/flask_multipass/providers/ldap/providers.py", line 191, in search_identities
    for _, user_data in self._search_users(search_filter):
  File "/home/adrian/dev/flask-multipass/flask_multipass/providers/ldap/operations.py", line 95, in search
    serverctrls=[page_ctrl], timeout=settings['timeout'])
  File "/home/adrian/dev/indico/env/lib/python2.7/site-packages/ldap/ldapobject.py", line 586, in search_ext
    timeout,sizelimit,
  File "/home/adrian/dev/indico/env/lib/python2.7/site-packages/ldap/ldapobject.py", line 106, in _ldap_call
    result = func(*args,**kwargs)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 7: ordinal not in range(128)

Potential fix below. Most likely needs to be applied in other places too (e.g. groups). Also, not sure whether UTF-8 always works with LDAP or if this depends on the LDAP server.

diff --git a/flask_multipass/providers/ldap/operations.py b/flask_multipass/providers/ldap/operations.py
index 16706ee..de71f90 100644
--- a/flask_multipass/providers/ldap/operations.py
+++ b/flask_multipass/providers/ldap/operations.py
@@ -89,6 +89,7 @@ def search(base_dn, search_filter, attributes):
     """
     connection, settings = current_ldap
     page_ctrl = SimplePagedResultsControl(True, size=settings['page_size'], cookie='')
+    search_filter = search_filter.encode('utf-8')

     while True:
         msg_id = connection.search_ext(base_dn, SCOPE_SUBTREE, filterstr=search_filter, attrlist=attributes,

SQLAlchemy provider uses FlaskForm from Flask-WTF which is not a dependency

A minor packaging issue I noticed while trying to clean up unused deps; flask_multipass.providers.sqlalchemy pulls FlaskForm from flask_multipass._compat which pulls it from flask_wtf which is not listed as a dependency of Flask-Multipass.

Choices for correction would appear to be listing Flask-WTF as a dependency of Flask-Multipass[sqlalchemy], or reworking flask_multipass._compat to reference wtforms.form.Form instead.

PyPI: please upload source distribution tarballs

Hi,

I am currently looking into adding flask-multipass to conda-forge but I cannot as there is no source distribution tarball available (generated with python setup.py sdist), which is the preferred format for building conda packages.

I would be most grateful if someone could look into this!

Many thanks in advance!

libldap version 2.5.13: cannot open shared object file

flask-multipass doesn't seem to work with versions of its system dependency libldap2-dev newer than 2.4. In an environment where libldap2-dev version 2.5.13 is installed, an application using flask-multipass will run into the following error, despite working perfectly wherever libldap2-dev e.g. 2.4.57 is available:

.venv/lib/python3.7/site-packages/flask_multipass/core.py:73: in init_app
    state.auth_providers = ImmutableDict(self._create_providers('AUTH', AuthProvider))
.venv/lib/python3.7/site-packages/flask_multipass/core.py:461: in _create_providers
    cls = resolve_provider_type(base, settings.pop('type'), registry)
.venv/lib/python3.7/site-packages/flask_multipass/util.py:153: in resolve_provider_type
    cls = entry_point.load()
.venv/lib/python3.7/site-packages/pkg_resources/__init__.py:2517: in load
    return self.resolve()
.venv/lib/python3.7/site-packages/pkg_resources/__init__.py:2523: in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
.venv/lib/python3.7/site-packages/flask_multipass/providers/ldap/__init__.py:7: in <module>
    from .providers import LDAPAuthProvider, LDAPGroup, LDAPIdentityProvider
.venv/lib/python3.7/site-packages/flask_multipass/providers/ldap/providers.py:10: in <module>
    from ldap import INVALID_CREDENTIALS
.venv/lib/python3.7/site-packages/ldap/__init__.py:34: in <module>
    import _ldap
E   ImportError: libldap_r-2.4.so.2: cannot open shared object file: No such file or directory

2.5.13 is the libldap2-dev version coming with Debian 12 (bookworm), which was released recently:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.