Projet

Général

Profil

0002-add-request-as-first-argument-to-all-backends-33992.patch

Benjamin Dauvergne, 14 juin 2019 15:24

Télécharger (15,8 ko)

Voir les différences:

Subject: [PATCH 2/2] add request as first argument to all backends (#33992)

 src/authentic2/api_views.py               |  8 +++++++-
 src/authentic2/backends/ldap_backend.py   |  2 +-
 src/authentic2/backends/models_backend.py |  6 ++----
 src/authentic2/forms/authentication.py    |  4 +---
 src/authentic2/utils.py                   |  9 +++++++--
 src/authentic2/views.py                   |  4 ++--
 src/authentic2_auth_fc/views.py           | 16 +++++++++++-----
 src/authentic2_auth_oidc/backends.py      |  2 +-
 src/authentic2_auth_oidc/views.py         |  6 +++---
 src/authentic2_auth_saml/backends.py      |  2 +-
 tests/test_all.py                         |  6 ++++--
 tests/test_api.py                         |  2 +-
 tests/test_backends.py                    |  2 +-
 tests/test_ldap.py                        |  3 ++-
 tests/test_utils.py                       |  3 +--
 15 files changed, 45 insertions(+), 30 deletions(-)
src/authentic2/api_views.py
17 17
import logging
18 18
import smtplib
19 19

  
20
import django
20 21
from django.db import models
21 22
from django.contrib.auth import get_user_model
22 23
from django.core.exceptions import MultipleObjectsReturned
......
34 35
from rest_framework.routers import SimpleRouter
35 36
from rest_framework.generics import GenericAPIView
36 37
from rest_framework.response import Response
37
from rest_framework import permissions, status
38
from rest_framework import permissions, status, authentication
38 39
from rest_framework.exceptions import PermissionDenied, AuthenticationFailed
39 40
from rest_framework.fields import CreateOnlyDefault
40 41
from rest_framework.decorators import list_route, detail_route
......
52 53
from .a2_rbac.utils import get_default_ou
53 54

  
54 55

  
56
# Retro-compatibility with Django 1.8
57
if django.VERSION < (1, 11):
58
    authentication.authenticate = utils.authenticate
59

  
60

  
55 61
class HookMixin(object):
56 62
    def get_serializer(self, *args, **kwargs):
57 63
        serializer = super(HookMixin, self).get_serializer(*args, **kwargs)
src/authentic2/backends/ldap_backend.py
1374 1374

  
1375 1375

  
1376 1376
class LDAPBackendPasswordLost(LDAPBackend):
1377
    def authenticate(self, user=None):
1377
    def authenticate(self, request, user=None):
1378 1378
        if not user:
1379 1379
            return
1380 1380
        config = self.get_config()
src/authentic2/backends/models_backend.py
68 68
        from .. import models
69 69
        return bool(models.PasswordReset.filter(user=user).count())
70 70

  
71
    def authenticate(self, username=None, password=None, realm=None, ou=None, **kwargs):
71
    def authenticate(self, request, username=None, password=None, realm=None, ou=None):
72 72
        UserModel = get_user_model()
73
        if username is None:
74
            username = kwargs.get(UserModel.USERNAME_FIELD)
75 73
        if not username:
76 74
            return
77 75
        query = self.get_query(username=username, realm=realm, ou=ou)
......
99 97

  
100 98

  
101 99
class DummyModelBackend(ModelBackend):
102
    def authenticate(self, user=None):
100
    def authenticate(self, request, user=None):
103 101
        if user is not None:
104 102
            return user
src/authentic2/forms/authentication.py
21 21
from django.contrib.auth import forms as auth_forms
22 22
from django.utils import html
23 23

  
24
from django.contrib.auth import authenticate
25

  
26 24
from authentic2.forms.fields import PasswordField
27 25

  
28 26
from ..a2_rbac.models import OrganizationalUnit as OU
......
98 96
        ou = self.cleaned_data.get('ou')
99 97

  
100 98
        if username is not None and password:
101
            self.user_cache = authenticate(username=username, password=password, ou=ou, request=self.request)
99
            self.user_cache = utils.authenticate(self.request, username=username, password=password, ou=ou)
102 100
            if self.user_cache is None:
103 101
                raise forms.ValidationError(
104 102
                    self.error_messages['invalid_login'],
src/authentic2/utils.py
32 32
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
33 33
from django.http.request import QueryDict
34 34
from django.contrib.auth import (REDIRECT_FIELD_NAME, login as auth_login, SESSION_KEY,
35
                                 HASH_SESSION_KEY, BACKEND_SESSION_KEY, authenticate,
35
                                 HASH_SESSION_KEY, BACKEND_SESSION_KEY, authenticate as dj_authenticate,
36 36
                                 get_user_model)
37 37
from django import forms
38 38
from django.forms.utils import ErrorList, to_current_timezone
......
834 834
        for key in (SESSION_KEY, BACKEND_SESSION_KEY, HASH_SESSION_KEY,
835 835
                    constants.LAST_LOGIN_SESSION_KEY):
836 836
            switched[key] = request.session[key]
837
        user = authenticate(user=new_user)
837
        user = authenticate(request, user=new_user)
838 838
        login(request, user, 'switch')
839 839
        request.session[constants.SWITCH_USER_SESSION_KEY] = switched
840 840
        if constants.LAST_LOGIN_SESSION_KEY not in request.session:
......
1144 1144
    if session is not None:
1145 1145
        return session.get(constants.AUTHENTICATION_EVENTS_SESSION_KEY, [])
1146 1146
    return []
1147

  
1148

  
1149
def authenticate(request=None, **kwargs):
1150
    # Compatibility layer with Django 1.8
1151
    return dj_authenticate(request=request, **kwargs)
src/authentic2/views.py
43 43
from django.contrib.auth.decorators import login_required
44 44
from django.db.models.fields import FieldDoesNotExist
45 45
from django.db.models.query import Q
46
from django.contrib.auth import get_user_model, authenticate
46
from django.contrib.auth import get_user_model
47 47
from django.http import Http404
48 48
from django.utils.http import urlsafe_base64_decode
49 49
from django.views.generic.edit import CreateView
......
690 690
        try:
691 691
            uid = urlsafe_base64_decode(uidb64)
692 692
            # use authenticate to eventually get an LDAPUser
693
            self.user = authenticate(user=UserModel._default_manager.get(pk=uid))
693
            self.user = utils.authenticate(request, user=UserModel._default_manager.get(pk=uid))
694 694
        except (TypeError, ValueError, OverflowError,
695 695
                UserModel.DoesNotExist):
696 696
            validlink = False
src/authentic2_auth_fc/views.py
26 26
import django
27 27
from django.views.generic import View, FormView
28 28
from django.http import HttpResponseRedirect, Http404
29
from django.contrib.auth import authenticate, REDIRECT_FIELD_NAME, get_user_model
29
from django.contrib.auth import REDIRECT_FIELD_NAME, get_user_model
30 30
from django.contrib import messages
31 31
from django.shortcuts import resolve_url, render
32 32
from django.utils.translation import ugettext as _
......
402 402

  
403 403
        default_ou = get_default_ou()
404 404
        email_is_unique = a2_app_settings.A2_EMAIL_IS_UNIQUE or default_ou.email_is_unique
405
        user = authenticate(sub=self.sub, user_info=self.user_info,
406
                            token=self.token)
405
        user = a2_utils.authenticate(
406
            request,
407
            sub=self.sub,
408
            user_info=self.user_info,
409
            token=self.token)
407 410
        if not user and self.user_info.get('email') and email_is_unique:
408 411
            email = self.user_info['email']
409 412
            User = get_user_model()
......
428 431
                            self.logger.info(u'fc link created sub %s user %s', self.sub, user)
429 432
                            hooks.call_hooks('event', name='fc-link', user=user, sub=self.sub,
430 433
                                             request=request)
431
                        user = authenticate(sub=self.sub, user_info=self.user_info,
432
                                            token=self.token)
434
                        user = a2_utils.authenticate(
435
                            request=request,
436
                            sub=self.sub,
437
                            user_info=self.user_info,
438
                            token=self.token)
433 439
                    else:
434 440
                        messages.warning(
435 441
                            request,
src/authentic2_auth_oidc/backends.py
36 36

  
37 37

  
38 38
class OIDCBackend(ModelBackend):
39
    def authenticate(self, access_token=None, id_token=None, nonce=None, **kwargs):
39
    def authenticate(self, request, access_token=None, id_token=None, nonce=None):
40 40
        logger = logging.getLogger(__name__)
41 41
        if id_token is None:
42 42
            return
src/authentic2_auth_oidc/views.py
23 23
from django.core.urlresolvers import reverse
24 24
from django.utils.translation import get_language, ugettext as _
25 25
from django.contrib import messages
26
from django.contrib.auth import REDIRECT_FIELD_NAME, authenticate
26
from django.contrib.auth import REDIRECT_FIELD_NAME
27 27
from django.conf import settings
28 28
from django.views.generic.base import View
29 29
from django.http import HttpResponseBadRequest
30 30

  
31 31
from authentic2.decorators import setting_enabled
32
from authentic2.utils import redirect, login, good_next_url
32
from authentic2.utils import redirect, login, good_next_url, authenticate
33 33

  
34 34
from . import app_settings, models
35 35
from .utils import get_provider, get_provider_by_issuer
......
198 198
            return self.continue_to_next_url()
199 199
        logger.info(u'got token response %s', result)
200 200
        access_token = result.get('access_token')
201
        user = authenticate(access_token=access_token, nonce=nonce, id_token=result['id_token'])
201
        user = authenticate(request, access_token=access_token, nonce=nonce, id_token=result['id_token'])
202 202
        if user:
203 203
            # remember last tokens for logout
204 204
            tokens = request.session.setdefault('auth_oidc', {}).setdefault('tokens', [])
src/authentic2_auth_saml/backends.py
22 22

  
23 23

  
24 24
class SAMLBackend(SAMLBackend):
25
    def authenticate(self, saml_attributes, request=None):
25
    def authenticate(self, request, saml_attributes):
26 26
        if not app_settings.enable:
27 27
            return None
28 28
        return super(SAMLBackend, self).authenticate(saml_attributes=saml_attributes, request=request)
tests/test_all.py
253 253
            user_editable=True,
254 254
            user_visible=True,
255 255
            kind='string')
256
        self.assertTrue(self.client.login(username='testbot',
256
        self.assertTrue(self.client.login(request=None,
257
                                          username='testbot',
257 258
                                          password='secret'))
258 259

  
259 260
        # get the edit page in order to check form's prefix
......
298 299
            user_visible=False,
299 300
            kind='string')
300 301

  
301
        self.assertTrue(self.client.login(username='testbot',
302
        self.assertTrue(self.client.login(request=None,
303
                                          username='testbot',
302 304
                                          password='secret'))
303 305
        response = self.client.get(reverse('profile_edit'))
304 306
        form = get_response_form(response)
tests/test_api.py
75 75
    assert response.content == b'{}'
76 76

  
77 77
    # login
78
    client.login(username='john.doe', password='password')
78
    client.login(request=None, username='john.doe', password='password')
79 79
    response = client.get('/api/user/', HTTP_ORIGIN='http://testserver')
80 80
    data = json.loads(response.content)
81 81
    assert isinstance(data, dict)
tests/test_backends.py
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17
from django.contrib.auth import authenticate
17
from authentic2.utils import authenticate
18 18
from authentic2.backends import is_user_authenticable
19 19

  
20 20

  
tests/test_ldap.py
24 24
from ldap.dn import escape_dn_chars
25 25

  
26 26
from ldaptools.slapd import Slapd, has_slapd
27
from django.contrib.auth import get_user_model, authenticate
27
from django.contrib.auth import get_user_model
28 28
from django.core.exceptions import ImproperlyConfigured
29 29
from django.core import management
30 30
from django.core import mail
......
35 35
from authentic2.a2_rbac.utils import get_default_ou
36 36
from django_rbac.utils import get_ou_model
37 37
from authentic2.backends import ldap_backend
38
from authentic2.utils import authenticate
38 39
from authentic2 import crypto, models
39 40

  
40 41
import utils
tests/test_utils.py
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16
# authentic2
17 17

  
18
from django.contrib.auth import authenticate
19 18
from django.contrib.auth.middleware import AuthenticationMiddleware
20 19
from django.contrib.sessions.middleware import SessionMiddleware
21 20

  
22 21
from authentic2.utils import (good_next_url, same_origin, select_next_url,
23 22
                              user_can_change_password, login,
24
                              get_authentication_events)
23
                              get_authentication_events, authenticate)
25 24

  
26 25

  
27 26
def test_good_next_url(db, rf, settings):
28
-