Projet

Général

Profil

0004-to-be-fixed-up-use-a-decorator-to-indicate-views-whe.patch

Benjamin Dauvergne, 23 juillet 2021 15:48

Télécharger (10,2 ko)

Voir les différences:

Subject: [PATCH 4/4] to be fixed up: use a decorator to indicate views where
 view_restriction can be applied

 src/authentic2/idp/saml/saml2_endpoints.py | 18 +++++-------------
 src/authentic2/middleware.py               |  7 +++----
 src/authentic2/utils/view_decorators.py    | 20 ++++++++++++++++++++
 src/authentic2/views.py                    |  8 +++-----
 src/authentic2_auth_fc/views.py            |  1 -
 src/authentic2_idp_cas/views.py            |  6 +++---
 src/authentic2_idp_oidc/views.py           |  5 ++---
 tests/test_user_manager.py                 |  2 +-
 8 files changed, 37 insertions(+), 30 deletions(-)
 create mode 100644 src/authentic2/utils/view_decorators.py
src/authentic2/idp/saml/saml2_endpoints.py
112 112
from authentic2.utils.misc import datetime_to_xs_datetime, find_authentication_event
113 113
from authentic2.utils.misc import get_backends as get_idp_backends
114 114
from authentic2.utils.misc import login_require, make_url
115
from authentic2.utils.view_decorators import enable_view_restriction
115 116

  
116 117
from . import app_settings
117 118

  
......
494 495
    return kwargs['name_id_content']
495 496

  
496 497

  
498
@enable_view_restriction
497 499
@never_cache
498 500
@csrf_exempt
499 501
@log_assert
......
624 626
    """
625 627
    nonce = login.request.id or get_nonce()
626 628
    save_key_values(nonce, force_text(login.dump()), False, nid_format)
627
    next_url = make_url(continue_sso, params={NONCE_FIELD_NAME: nonce})
629
    next_url = make_url('a2-idp-saml-continue', params={NONCE_FIELD_NAME: nonce})
628 630
    logger.debug('redirect to login page with next url %s', next_url)
629 631
    return login_require(
630 632
        request,
......
662 664
    return HttpResponseRedirect(url)
663 665

  
664 666

  
667
@enable_view_restriction
665 668
@never_cache
666 669
def continue_sso(request):
667 670
    consent_answer = None
......
1025 1028
    return request.user.is_superuser()
1026 1029

  
1027 1030

  
1031
@enable_view_restriction
1028 1032
@never_cache
1029 1033
@csrf_exempt
1030 1034
@login_required
......
1126 1130
    return return_saml2_response(request, logout, title=_('You are being redirected to "%s"') % provider.name)
1127 1131

  
1128 1132

  
1129
finish_slo.no_view_restriction = True
1130

  
1131

  
1132 1133
def return_logout_error(request, logout, error):
1133 1134
    logout.buildResponseMsg()
1134 1135
    set_saml2_response_responder_status_code(logout.response, error)
......
1448 1449
    return a2_views.logout(request, next_url=next_url, do_local=False, check_referer=False)
1449 1450

  
1450 1451

  
1451
slo.no_view_restriction = True
1452

  
1453

  
1454 1452
def icon_url(name):
1455 1453
    return '%s/authentic2/images/%s.png' % (settings.STATIC_URL, name)
1456 1454

  
......
1535 1533
        return HttpResponseRedirect(logout.msgUrl)
1536 1534

  
1537 1535

  
1538
idp_slo.no_view_restriction = True
1539

  
1540

  
1541 1536
def process_logout_response(request, logout, soap_response, next):
1542 1537
    logger.debug('logout response is %r', soap_response)
1543 1538
    try:
......
1579 1574
    return process_logout_response(request, logout, get_saml2_query_request(request), next)
1580 1575

  
1581 1576

  
1582
slo_return.no_view_restriction = True
1583

  
1584

  
1585 1577
# Helpers
1586 1578

  
1587 1579
# Mapping to generate the metadata file, must be kept in sync with the url
src/authentic2/middleware.py
166 166

  
167 167
    def process_view(self, request, view_func, view_args, view_kwargs):
168 168
        '''If current view is not the one where we should be, redirect'''
169
        if not getattr(view_func, 'enable_view_restriction', False):
170
            return
171

  
169 172
        view = self.check_view_restrictions(request)
170 173
        if not view:
171 174
            return
......
174 177
        # do not block on the restricted view
175 178
        if url_name == view:
176 179
            return
177

  
178
        # prevent blocking some views, like logout views
179
        if getattr(request.resolver_match.func, 'no_view_restriction', False):
180
            return
181 180
        return utils_misc.redirect_and_come_back(request, view)
182 181

  
183 182

  
src/authentic2/utils/view_decorators.py
1
# authentic2 - versatile identity manager
2
# Copyright (C) 2010-2021 Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17

  
18
def enable_view_restriction(view):
19
    view.enable_view_restriction = True
20
    return view
src/authentic2/views.py
63 63
from .utils import switch_user as utils_switch_user
64 64
from .utils.evaluate import HTTPHeaders
65 65
from .utils.service import get_service_from_request, get_service_from_token, set_service_ref
66
from .utils.view_decorators import enable_view_restriction
66 67

  
67 68
User = get_user_model()
68 69

  
......
427 428
        return ctx
428 429

  
429 430

  
430
homepage = Homepage.as_view()
431
homepage = enable_view_restriction(Homepage.as_view())
431 432

  
432 433

  
433 434
class ProfileView(cbv.TemplateNamesMixin, TemplateView):
......
559 560
        return context
560 561

  
561 562

  
562
profile = login_required(ProfileView.as_view())
563
profile = enable_view_restriction(login_required(ProfileView.as_view()))
563 564

  
564 565

  
565 566
def logout_list(request):
......
630 631
    return response
631 632

  
632 633

  
633
logout.no_view_restriction = True
634

  
635

  
636 634
def login_password_profile(request, *args, **kwargs):
637 635
    context = kwargs.pop('context', {})
638 636
    can_change_password = utils_misc.user_can_change_password(request=request)
src/authentic2_auth_fc/views.py
572 572

  
573 573

  
574 574
logout = LogoutReturnView.as_view()
575
logout.no_view_restriction = True
src/authentic2_idp_cas/views.py
36 36
    normalize_attribute_values,
37 37
    redirect,
38 38
)
39
from authentic2.utils.view_decorators import enable_view_restriction
39 40
from authentic2.views import logout as logout_view
40 41
from authentic2_idp_cas.constants import (
41 42
    ATTRIBUTES_ELT,
......
467 468
        return redirect(request, next_url)
468 469

  
469 470

  
470
login = LoginView.as_view()
471
login = enable_view_restriction(LoginView.as_view())
471 472
logout = LogoutView.as_view()
472
logout.no_view_restriction = True
473
_continue = ContinueView.as_view()
473
_continue = enable_view_restriction(ContinueView.as_view())
474 474
validate = ValidateView.as_view()
475 475
service_validate = ServiceValidateView.as_view()
476 476
proxy = ProxyView.as_view()
src/authentic2_idp_oidc/views.py
48 48
from authentic2.decorators import setting_enabled
49 49
from authentic2.exponential_retry_timeout import ExponentialRetryTimeout
50 50
from authentic2.utils.misc import last_authentication_event, login_require, make_url, redirect
51
from authentic2.utils.view_decorators import enable_view_restriction
51 52
from authentic2.views import logout as a2_logout
52 53
from django_rbac.utils import get_ou_model
53 54

  
......
228 229
    return HttpResponse(utils.get_jwkset().export(private_keys=False), content_type='application/json')
229 230

  
230 231

  
232
@enable_view_restriction
231 233
@setting_enabled('ENABLE', settings=app_settings)
232 234
def authorize(request, *args, **kwargs):
233 235
    validated_redirect_uri = None
......
811 813
    # FIXME: do something with id_token_hint
812 814
    id_token_hint = request.GET.get('id_token_hint')
813 815
    return a2_logout(request, next_url=post_logout_redirect_uri, do_local=False, check_referer=False)
814

  
815

  
816
logout.no_view_restriction = True
tests/test_user_manager.py
336 336
    user_count = User.objects.count()
337 337
    # queries should be batched to keep prefetching working without
338 338
    # overspending memory for the queryset cache, 4 queries by batches
339
    num_queries = int(4 + 4 * (user_count / DEFAULT_BATCH_SIZE + bool(user_count % DEFAULT_BATCH_SIZE)))
339
    num_queries = int(4 * (user_count / DEFAULT_BATCH_SIZE + bool(user_count % DEFAULT_BATCH_SIZE)))
340 340
    # export task also perform one query to set trigram an another to get users count
341 341
    num_queries += 3
342 342
    with django_assert_num_queries(num_queries):
343
-