Projet

Général

Profil

0001-auth_oidc-add-a-sub-to-email-matching-strategy-60488.patch

Paul Marillonnet, 11 janvier 2022 10:03

Télécharger (5,07 ko)

Voir les différences:

Subject: [PATCH] auth_oidc: add a sub-to-email matching strategy (#60488)

 src/authentic2_auth_oidc/backends.py          |  7 ++++
 .../migrations/0004_auto_20171017_1522.py     |  1 +
 src/authentic2_auth_oidc/models.py            |  2 +
 tests/test_auth_oidc.py                       | 39 +++++++++++++++++++
 4 files changed, 49 insertions(+)
src/authentic2_auth_oidc/backends.py
149 149
            else:
150 150
                user = users[0]
151 151
                logger.info('auth_oidc: found user using username (=sub) "%s": %s', id_token.sub, user)
152
        elif provider.strategy == models.OIDCProvider.STRATEGY_FIND_EMAIL:
153
            users = User.objects.filter(email=id_token.sub, is_active=True).order_by('pk')
154
            if not users:
155
                logger.warning('auth_oidc: user with email (=sub) "%s" not found', id_token.sub)
156
            else:
157
                user = users[0]
158
                logger.info('auth_oidc: found user using email (=sub) "%s": %s', id_token.sub, user)
152 159
        else:
153 160
            try:
154 161
                user = User.objects.get(
src/authentic2_auth_oidc/migrations/0004_auto_20171017_1522.py
18 18
                    ('create', 'create'),
19 19
                    ('find-uuid', 'use sub to find existing user through UUID'),
20 20
                    ('find-username', 'use sub to find existing user through username'),
21
                    ('find-email', 'use sub to find existing user through email'),
21 22
                    ('none', 'none'),
22 23
                ],
23 24
            ),
src/authentic2_auth_oidc/models.py
42 42
    STRATEGY_CREATE = 'create'
43 43
    STRATEGY_FIND_UUID = 'find-uuid'
44 44
    STRATEGY_FIND_USERNAME = 'find-username'
45
    STRATEGY_FIND_EMAIL = 'find-email'
45 46
    STRATEGY_NONE = 'none'
46 47

  
47 48
    STRATEGIES = [
48 49
        (STRATEGY_CREATE, _('create')),
49 50
        (STRATEGY_FIND_UUID, _('use sub to find existing user through UUID')),
50 51
        (STRATEGY_FIND_USERNAME, _('use sub to find existing user through username')),
52
        (STRATEGY_FIND_EMAIL, _('use sub to find existing user through email')),
51 53
        (STRATEGY_NONE, _('none')),
52 54
    ]
53 55
    ALGO_NONE = 0
tests/test_auth_oidc.py
954 954
            response = app.get(login_callback_url(oidc_provider), params={'code': code, 'state': state})
955 955

  
956 956

  
957
def test_strategy_find_email(app, caplog, code, oidc_provider, oidc_provider_jwkset, simple_user):
958
    # no mapping please
959
    OIDCClaimMapping.objects.all().delete()
960
    oidc_provider.strategy = oidc_provider.STRATEGY_FIND_EMAIL
961
    oidc_provider.save()
962

  
963
    assert User.objects.count() == 1
964

  
965
    response = app.get('/').maybe_follow()
966
    assert oidc_provider.name in response.text
967
    response = response.click(oidc_provider.name)
968
    location = urllib.parse.urlparse(response.location)
969
    query = QueryDict(location.query)
970
    state = query['state']
971
    nonce = query['nonce']
972

  
973
    # sub=simple_user.uuid MUST not work
974
    with utils.check_log(caplog, 'cannot create user'):
975
        with oidc_provider_mock(oidc_provider, oidc_provider_jwkset, code, sub=simple_user.uuid, nonce=nonce):
976
            response = app.get(login_callback_url(oidc_provider), params={'code': code, 'state': state})
977

  
978
    # sub=john.doe, MUST not work
979
    with utils.check_log(caplog, 'cannot create user'):
980
        with oidc_provider_mock(
981
            oidc_provider, oidc_provider_jwkset, code, nonce=nonce, sub=simple_user.username
982
        ):
983
            response = app.get(login_callback_url(oidc_provider), params={'code': code, 'state': state})
984

  
985
    simple_user.email = 'john.doe@example.org'
986
    simple_user.save()
987

  
988
    # sub=john.doe@example.org, MUST work
989
    with utils.check_log(caplog, 'found user using email'):
990
        with oidc_provider_mock(
991
            oidc_provider, oidc_provider_jwkset, code, nonce=nonce, sub=simple_user.email
992
        ):
993
            response = app.get(login_callback_url(oidc_provider), params={'code': code, 'state': state})
994

  
995

  
957 996
def test_error_access_denied(app, caplog):
958 997
    oidc_provider = make_oidc_provider()
959 998
    response = app.get('/login/')
960
-