0004-to-be-fixed-up-use-a-decorator-to-indicate-views-whe.patch
src/authentic2/idp/saml/saml2_endpoints.py | ||
---|---|---|
1126 | 1126 |
return return_saml2_response(request, logout, title=_('You are being redirected to "%s"') % provider.name) |
1127 | 1127 | |
1128 | 1128 | |
1129 |
finish_slo.no_view_restriction = True |
|
1130 | ||
1131 | ||
1132 | 1129 |
def return_logout_error(request, logout, error): |
1133 | 1130 |
logout.buildResponseMsg() |
1134 | 1131 |
set_saml2_response_responder_status_code(logout.response, error) |
... | ... | |
1448 | 1445 |
return a2_views.logout(request, next_url=next_url, do_local=False, check_referer=False) |
1449 | 1446 | |
1450 | 1447 | |
1451 |
slo.no_view_restriction = True |
|
1452 | ||
1453 | ||
1454 | 1448 |
def icon_url(name): |
1455 | 1449 |
return '%s/authentic2/images/%s.png' % (settings.STATIC_URL, name) |
1456 | 1450 | |
... | ... | |
1535 | 1529 |
return HttpResponseRedirect(logout.msgUrl) |
1536 | 1530 | |
1537 | 1531 | |
1538 |
idp_slo.no_view_restriction = True |
|
1539 | ||
1540 | ||
1541 | 1532 |
def process_logout_response(request, logout, soap_response, next): |
1542 | 1533 |
logger.debug('logout response is %r', soap_response) |
1543 | 1534 |
try: |
... | ... | |
1579 | 1570 |
return process_logout_response(request, logout, get_saml2_query_request(request), next) |
1580 | 1571 | |
1581 | 1572 | |
1582 |
slo_return.no_view_restriction = True |
|
1583 | ||
1584 | ||
1585 | 1573 |
# Helpers |
1586 | 1574 | |
1587 | 1575 |
# Mapping to generate the metadata file, must be kept in sync with the url |
src/authentic2/idp/saml/urls.py | ||
---|---|---|
28 | 28 |
slo_soap, |
29 | 29 |
sso, |
30 | 30 |
) |
31 |
from authentic2.utils.view_decorators import view_restriction |
|
31 | 32 | |
32 | 33 |
from . import views |
33 | 34 | |
34 | 35 |
urlpatterns = [ |
35 | 36 |
url(r'^metadata$', metadata, name='a2-idp-saml-metadata'), |
36 |
url(r'^sso$', sso, name='a2-idp-saml-sso'),
|
|
37 |
url(r'^continue$', continue_sso, name='a2-idp-saml-continue'),
|
|
37 |
url(r'^sso$', view_restriction(sso), name='a2-idp-saml-sso'),
|
|
38 |
url(r'^continue$', view_restriction(continue_sso), name='a2-idp-saml-continue'),
|
|
38 | 39 |
url(r'^slo$', slo, name='a2-idp-saml-slo'), |
39 | 40 |
url(r'^slo/soap$', slo_soap, name='a2-idp-saml-slo-soap'), |
40 | 41 |
url(r'^idp_slo/(.*)$', idp_slo, name='a2-idp-saml-slo-idp'), |
... | ... | |
42 | 43 |
url(r'^finish_slo$', finish_slo, name='a2-idp-saml-finish-slo'), |
43 | 44 |
url(r'^artifact$', artifact, name='a2-idp-saml-artifact'), |
44 | 45 |
# legacy endpoint, now it's prefered to pass the entity_id in a parameter |
45 |
url(r'^idp_sso/(.+)$', idp_sso, name='a2-idp-saml-idp-sso-named'),
|
|
46 |
url(r'^idp_sso/$', idp_sso, name='a2-idp-saml2-idp-sso'),
|
|
46 |
url(r'^idp_sso/(.+)$', view_restriction(idp_sso), name='a2-idp-saml-idp-sso-named'),
|
|
47 |
url(r'^idp_sso/$', view_restriction(idp_sso), name='a2-idp-saml2-idp-sso'),
|
|
47 | 48 |
url(r'^federations/create/(?P<pk>\d+)/$', views.create_federation, name='a2-idp-saml2-federation-create'), |
48 | 49 |
url(r'^federations/(?P<pk>\d+)/delete/$', views.delete_federation, name='a2-idp-saml2-federation-delete'), |
49 | 50 |
] |
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, 'view_restriction', False): |
|
170 |
return |
|
169 | 171 |
view = self.check_view_restrictions(request) |
170 | 172 |
if not view: |
171 | 173 |
return |
... | ... | |
174 | 176 |
# do not block on the restricted view |
175 | 177 |
if url_name == view: |
176 | 178 |
return |
177 | ||
178 |
# prevent blocking some views, like logout views |
|
179 |
if getattr(request.resolver_match.func, 'no_view_restriction', False): |
|
180 |
return |
|
181 | 179 |
return utils_misc.redirect_and_come_back(request, view) |
182 | 180 | |
183 | 181 |
src/authentic2/urls.py | ||
---|---|---|
34 | 34 |
from authentic2.decorators import lasso_required, required, setting_enabled |
35 | 35 | |
36 | 36 |
from . import plugins, views |
37 |
from .utils.view_decorators import view_restriction |
|
37 | 38 | |
38 | 39 |
admin.autodiscover() |
39 | 40 | |
... | ... | |
67 | 68 |
login_required(views.authorized_oauth_services), |
68 | 69 |
name='authorized-oauth-services', |
69 | 70 |
), |
70 |
url(r'^$', views.profile, name='account_management'),
|
|
71 |
url(r'^$', view_restriction(views.profile), name='account_management'),
|
|
71 | 72 |
# Password change |
72 | 73 |
url(r'^password/change/$', views.password_change, name='password_change'), |
73 | 74 |
url( |
... | ... | |
99 | 100 |
] |
100 | 101 | |
101 | 102 |
urlpatterns = [ |
102 |
url(r'^$', views.homepage, name='auth_homepage'),
|
|
103 |
url(r'^$', view_restriction(views.homepage), name='auth_homepage'),
|
|
103 | 104 |
url(r'^login/$', views.login, name='auth_login'), |
104 | 105 |
url(r'^logout/$', views.logout, name='auth_logout'), |
105 | 106 |
url(r'^su/(?P<uuid>[A-Za-z0-9_-]+)/$', views.su, name='su'), |
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 |
import copy |
|
18 |
import functools |
|
19 |
import types |
|
20 | ||
21 | ||
22 |
def copy_callable(f): |
|
23 |
"""Based on http://stackoverflow.com/a/6528148/190597 (Glenn Maynard)""" |
|
24 |
assert hasattr(f, '__call__') |
|
25 | ||
26 |
if isinstance(f, types.FunctionType): |
|
27 |
g = types.FunctionType( |
|
28 |
f.__code__, f.__globals__, name=f.__name__, argdefs=f.__defaults__, closure=f.__closure__ |
|
29 |
) |
|
30 |
g = functools.update_wrapper(g, f) |
|
31 |
g.__kwdefaults__ = f.__kwdefaults__ |
|
32 |
return g |
|
33 |
else: |
|
34 |
return copy.copy(f) |
|
35 | ||
36 | ||
37 |
def view_restriction(view): |
|
38 |
decorated_view = copy_callable(view) |
|
39 |
decorated_view.view_restriction = True |
|
40 |
return decorated_view |
src/authentic2/views.py | ||
---|---|---|
630 | 630 |
return response |
631 | 631 | |
632 | 632 | |
633 |
logout.no_view_restriction = True |
|
634 | ||
635 | ||
636 | 633 |
def login_password_profile(request, *args, **kwargs): |
637 | 634 |
context = kwargs.pop('context', {}) |
638 | 635 |
can_change_password = utils_misc.user_can_change_password(request=request) |
src/authentic2_idp_cas/urls.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
from django.conf.urls import url |
18 | 18 | |
19 |
from authentic2.utils.view_decorators import view_restriction |
|
20 | ||
19 | 21 |
from . import views |
20 | 22 | |
21 | 23 |
urlpatterns = [ |
22 |
url('^login/?$', views.login, name='a2-idp-cas-login'),
|
|
23 |
url('^continue/$', views._continue, name='a2-idp-cas-continue'),
|
|
24 |
url('^login/?$', view_restriction(views.login), name='a2-idp-cas-login'),
|
|
25 |
url('^continue/$', view_restriction(views._continue), name='a2-idp-cas-continue'),
|
|
24 | 26 |
url('^validate/?$', views.validate, name='a2-idp-cas-validate'), |
25 | 27 |
url('^serviceValidate/?$', views.service_validate, name='a2-idp-cas-service-validate'), |
26 | 28 |
url('^logout/?$', views.logout, name='a2-idp-cas-logout'), |
src/authentic2_idp_oidc/urls.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
from django.conf.urls import url |
18 | 18 | |
19 |
from authentic2.utils.view_decorators import view_restriction |
|
20 | ||
19 | 21 |
from . import views |
20 | 22 | |
21 | 23 |
urlpatterns = [ |
22 | 24 |
url(r'^.well-known/openid-configuration$', views.openid_configuration, name='oidc-openid-configuration'), |
23 | 25 |
url(r'^idp/oidc/certs/?$', views.certs, name='oidc-certs'), |
24 |
url(r'^idp/oidc/authorize/?$', views.authorize, name='oidc-authorize'),
|
|
26 |
url(r'^idp/oidc/authorize/?$', view_restriction(views.authorize), name='oidc-authorize'),
|
|
25 | 27 |
url(r'^idp/oidc/token/?$', views.token, name='oidc-token'), |
26 | 28 |
url(r'^idp/oidc/user_info/?$', views.user_info, name='oidc-user-info'), |
27 | 29 |
url(r'^idp/oidc/logout/?$', views.logout, name='oidc-logout'), |
28 |
- |