0003-misc-move-hooks-module-in-utils-package-69720.patch
src/authentic2/api_views.py | ||
---|---|---|
54 | 54 | |
55 | 55 |
from authentic2.compat.drf import action |
56 | 56 | |
57 |
from . import api_mixins, app_settings, decorators, hooks
|
|
57 |
from . import api_mixins, app_settings, decorators |
|
58 | 58 |
from .a2_rbac.models import OrganizationalUnit, Role, RoleParenting |
59 | 59 |
from .a2_rbac.utils import get_default_ou |
60 | 60 |
from .apps.journal.models import Event |
... | ... | |
62 | 62 |
from .journal_event_types import UserLogin, UserRegistration |
63 | 63 |
from .models import APIClient, Attribute, PasswordReset, Service |
64 | 64 |
from .passwords import get_password_checker, get_password_strength |
65 |
from .utils import hooks |
|
65 | 66 |
from .utils import misc as utils_misc |
66 | 67 |
from .utils.api import DjangoRBACPermission, NaturalKeyRelatedField |
67 | 68 |
from .utils.lookups import Unaccent |
src/authentic2/cbv.py | ||
---|---|---|
20 | 20 |
from django.utils.decorators import method_decorator |
21 | 21 |
from django.views.decorators.csrf import csrf_exempt, ensure_csrf_cookie |
22 | 22 | |
23 |
from . import hooks |
|
23 |
from .utils import hooks
|
|
24 | 24 |
from .utils import misc as utils_misc |
25 | 25 |
from .utils.views import csrf_token_check |
26 | 26 |
src/authentic2/forms/passwords.py | ||
---|---|---|
28 | 28 |
from authentic2.journal import journal |
29 | 29 |
from authentic2.passwords import get_min_password_strength |
30 | 30 | |
31 |
from .. import app_settings, hooks, models, validators
|
|
31 |
from .. import app_settings, models, validators |
|
32 | 32 |
from ..backends import get_user_queryset |
33 |
from ..utils import hooks |
|
33 | 34 |
from ..utils import misc as utils_misc |
34 | 35 |
from .fields import CheckPasswordField, NewPasswordField, PasswordField, ValidatedEmailField |
35 | 36 |
from .honeypot import HoneypotForm |
src/authentic2/hooks.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 |
import logging |
|
18 | ||
19 |
from django.apps import apps |
|
20 |
from django.conf import settings |
|
21 | ||
22 |
from . import decorators |
|
23 |
from .utils.cache import GlobalCache |
|
24 | ||
25 | ||
26 |
@GlobalCache |
|
27 |
def get_hooks(hook_name): |
|
28 |
"""Return a list of defined hook named a2_hook<hook_name> on AppConfig classes of installed |
|
29 |
Django applications. |
|
30 | ||
31 |
Ordering of hooks can be defined using an orer field on the hook method. |
|
32 |
""" |
|
33 |
hooks = [] |
|
34 |
for app in apps.get_app_configs(): |
|
35 |
name = 'a2_hook_' + hook_name |
|
36 |
if hasattr(app, name): |
|
37 |
hooks.append(getattr(app, name)) |
|
38 |
if hasattr(settings, 'A2_HOOKS') and hasattr(settings.A2_HOOKS, 'items'): |
|
39 |
v = settings.A2_HOOKS.get(hook_name) |
|
40 |
if callable(v): |
|
41 |
hooks.append(v) |
|
42 |
v = settings.A2_HOOKS.get('__all__') |
|
43 |
if callable(v): |
|
44 |
hooks.append(lambda *args, **kwargs: v(hook_name, *args, **kwargs)) |
|
45 |
hooks.sort(key=lambda hook: getattr(hook, 'order', 0)) |
|
46 |
return hooks |
|
47 | ||
48 | ||
49 |
@decorators.to_list |
|
50 |
def call_hooks(hook_name, *args, **kwargs): |
|
51 |
'''Call each a2_hook_<hook_name> and return the list of results.''' |
|
52 |
logger = logging.getLogger(__name__) |
|
53 |
hooks = get_hooks(hook_name) |
|
54 |
for hook in hooks: |
|
55 |
try: |
|
56 |
yield hook(*args, **kwargs) |
|
57 |
except Exception: |
|
58 |
if getattr(settings, 'A2_HOOKS_PROPAGATE_EXCEPTIONS', False): |
|
59 |
raise |
|
60 |
logger.exception('exception while calling hook %s', hook) |
|
61 | ||
62 | ||
63 |
def call_hooks_first_result(hook_name, *args, **kwargs): |
|
64 |
'''Call each a2_hook_<hook_name> and return the first not None result.''' |
|
65 |
logger = logging.getLogger(__name__) |
|
66 |
hooks = get_hooks(hook_name) |
|
67 |
for hook in hooks: |
|
68 |
try: |
|
69 |
result = hook(*args, **kwargs) |
|
70 |
if result is not None: |
|
71 |
return result |
|
72 |
except Exception: |
|
73 |
if getattr(settings, 'A2_HOOKS_PROPAGATE_EXCEPTIONS', False): |
|
74 |
raise |
|
75 |
logger.exception('exception while calling hook %s', hook) |
|
17 |
from .utils.hooks import call_hooks, call_hooks_first_result, get_hooks # pylint: disable=unused-import |
src/authentic2/idp/saml/saml2_endpoints.py | ||
---|---|---|
58 | 58 |
from django.views.decorators.csrf import csrf_exempt |
59 | 59 |
from django.views.decorators.http import require_POST |
60 | 60 | |
61 |
from authentic2 import hooks |
|
62 | 61 |
from authentic2 import views as a2_views |
63 | 62 |
from authentic2.attributes_ng.engine import get_attributes |
64 | 63 |
from authentic2.compat_lasso import lasso |
... | ... | |
109 | 108 |
saml2_urn_to_nidformat, |
110 | 109 |
save_key_values, |
111 | 110 |
) |
111 |
from authentic2.utils import hooks |
|
112 | 112 |
from authentic2.utils import misc as utils_misc |
113 | 113 |
from authentic2.utils.misc import datetime_to_xs_datetime, find_authentication_event |
114 | 114 |
from authentic2.utils.misc import get_backends as get_idp_backends |
src/authentic2/manager/role_views.py | ||
---|---|---|
33 | 33 |
from django.views.generic import DetailView, FormView, TemplateView |
34 | 34 |
from django.views.generic.detail import SingleObjectMixin |
35 | 35 | |
36 |
from authentic2 import data_transfer, hooks
|
|
36 |
from authentic2 import data_transfer |
|
37 | 37 |
from authentic2.a2_rbac.models import OrganizationalUnit, Permission, Role, RoleParenting |
38 | 38 |
from authentic2.a2_rbac.utils import get_default_ou |
39 | 39 |
from authentic2.apps.journal.views import JournalViewWithContext |
40 | 40 |
from authentic2.forms.profile import modelform_factory |
41 |
from authentic2.utils import crypto |
|
41 |
from authentic2.utils import crypto, hooks
|
|
42 | 42 |
from authentic2.utils.misc import redirect |
43 | 43 | |
44 | 44 |
from . import forms, resources, tables, views |
src/authentic2/manager/user_views.py | ||
---|---|---|
37 | 37 |
from django.views.generic.detail import SingleObjectMixin |
38 | 38 |
from django.views.generic.edit import BaseFormView |
39 | 39 | |
40 |
from authentic2 import hooks |
|
41 | 40 |
from authentic2.a2_rbac.models import OrganizationalUnit, Role, RoleParenting |
42 | 41 |
from authentic2.a2_rbac.utils import get_default_ou |
43 | 42 |
from authentic2.apps.journal.views import JournalViewWithContext |
44 | 43 |
from authentic2.models import Attribute, PasswordReset |
45 |
from authentic2.utils import spooler, switch_user |
|
44 |
from authentic2.utils import hooks, spooler, switch_user
|
|
46 | 45 |
from authentic2.utils.misc import make_url, redirect, select_next_url, send_password_reset_mail |
47 | 46 |
from authentic2_idp_oidc.models import OIDCAuthorization, OIDCClient |
48 | 47 |
src/authentic2/manager/views.py | ||
---|---|---|
39 | 39 |
from django_tables2 import SingleTableMixin, SingleTableView |
40 | 40 |
from gadjo.templatetags.gadjo import xstatic |
41 | 41 | |
42 |
from authentic2 import hooks |
|
43 | 42 |
from authentic2.a2_rbac.models import OrganizationalUnit |
44 | 43 |
from authentic2.backends import ldap_backend |
45 | 44 |
from authentic2.data_transfer import ImportContext, export_site, import_site |
46 | 45 |
from authentic2.decorators import json as json_view |
47 | 46 |
from authentic2.forms.profile import modelform_factory |
48 |
from authentic2.utils import crypto |
|
47 |
from authentic2.utils import crypto, hooks
|
|
49 | 48 |
from authentic2.utils.misc import batch_queryset, redirect |
50 | 49 | |
51 | 50 |
from . import app_settings, forms, utils, widgets |
src/authentic2/utils/hooks.py | ||
---|---|---|
1 |
# authentic2 - versatile identity manager |
|
2 |
# Copyright (C) 2010-2019 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 logging |
|
18 | ||
19 |
from django.apps import apps |
|
20 |
from django.conf import settings |
|
21 | ||
22 |
from authentic2 import decorators |
|
23 |
from authentic2.utils.cache import GlobalCache |
|
24 | ||
25 | ||
26 |
@GlobalCache |
|
27 |
def get_hooks(hook_name): |
|
28 |
"""Return a list of defined hook named a2_hook<hook_name> on AppConfig classes of installed |
|
29 |
Django applications. |
|
30 | ||
31 |
Ordering of hooks can be defined using an orer field on the hook method. |
|
32 |
""" |
|
33 |
hooks = [] |
|
34 |
for app in apps.get_app_configs(): |
|
35 |
name = 'a2_hook_' + hook_name |
|
36 |
if hasattr(app, name): |
|
37 |
hooks.append(getattr(app, name)) |
|
38 |
if hasattr(settings, 'A2_HOOKS') and hasattr(settings.A2_HOOKS, 'items'): |
|
39 |
v = settings.A2_HOOKS.get(hook_name) |
|
40 |
if callable(v): |
|
41 |
hooks.append(v) |
|
42 |
v = settings.A2_HOOKS.get('__all__') |
|
43 |
if callable(v): |
|
44 |
hooks.append(lambda *args, **kwargs: v(hook_name, *args, **kwargs)) |
|
45 |
hooks.sort(key=lambda hook: getattr(hook, 'order', 0)) |
|
46 |
return hooks |
|
47 | ||
48 | ||
49 |
@decorators.to_list |
|
50 |
def call_hooks(hook_name, *args, **kwargs): |
|
51 |
'''Call each a2_hook_<hook_name> and return the list of results.''' |
|
52 |
logger = logging.getLogger(__name__) |
|
53 |
hooks = get_hooks(hook_name) |
|
54 |
for hook in hooks: |
|
55 |
try: |
|
56 |
yield hook(*args, **kwargs) |
|
57 |
except Exception: |
|
58 |
if getattr(settings, 'A2_HOOKS_PROPAGATE_EXCEPTIONS', False): |
|
59 |
raise |
|
60 |
logger.exception('exception while calling hook %s', hook) |
|
61 | ||
62 | ||
63 |
def call_hooks_first_result(hook_name, *args, **kwargs): |
|
64 |
'''Call each a2_hook_<hook_name> and return the first not None result.''' |
|
65 |
logger = logging.getLogger(__name__) |
|
66 |
hooks = get_hooks(hook_name) |
|
67 |
for hook in hooks: |
|
68 |
try: |
|
69 |
result = hook(*args, **kwargs) |
|
70 |
if result is not None: |
|
71 |
return result |
|
72 |
except Exception: |
|
73 |
if getattr(settings, 'A2_HOOKS_PROPAGATE_EXCEPTIONS', False): |
|
74 |
raise |
|
75 |
logger.exception('exception while calling hook %s', hook) |
src/authentic2/utils/misc.py | ||
---|---|---|
455 | 455 |
def login(request, user, how, nonce=None, record=True, **kwargs): |
456 | 456 |
"""Login a user model, record the authentication event and redirect to next |
457 | 457 |
URL or settings.LOGIN_REDIRECT_URL.""" |
458 |
from .. import hooks
|
|
458 |
from . import hooks |
|
459 | 459 |
from .service import get_service |
460 | 460 |
from .views import check_cookie_works |
461 | 461 |
src/authentic2/views.py | ||
---|---|---|
58 | 58 |
from authentic2.forms import authentication as authentication_forms |
59 | 59 |
from authentic2_idp_oidc.models import OIDCAuthorization |
60 | 60 | |
61 |
from . import app_settings, attribute_kinds, cbv, constants, decorators, hooks, models, validators
|
|
61 |
from . import app_settings, attribute_kinds, cbv, constants, decorators, models, validators |
|
62 | 62 |
from .a2_rbac.models import OrganizationalUnit as OU |
63 | 63 |
from .a2_rbac.utils import get_default_ou |
64 | 64 |
from .forms import passwords as passwords_forms |
65 | 65 |
from .forms import profile as profile_forms |
66 | 66 |
from .forms import registration as registration_forms |
67 | 67 |
from .models import Lock |
68 |
from .utils import crypto |
|
68 |
from .utils import crypto, hooks
|
|
69 | 69 |
from .utils import misc as utils_misc |
70 | 70 |
from .utils import switch_user as utils_switch_user |
71 | 71 |
from .utils.evaluate import make_condition_context |
src/authentic2_auth_fc/views.py | ||
---|---|---|
37 | 37 |
from requests_oauthlib import OAuth2Session |
38 | 38 | |
39 | 39 |
from authentic2 import app_settings as a2_app_settings |
40 |
from authentic2 import constants, hooks
|
|
40 |
from authentic2 import constants |
|
41 | 41 |
from authentic2.a2_rbac.utils import get_default_ou |
42 | 42 |
from authentic2.forms.passwords import SetPasswordForm |
43 | 43 |
from authentic2.models import Attribute, AttributeValue, Lock |
44 |
from authentic2.utils import hooks |
|
44 | 45 |
from authentic2.utils import misc as utils_misc |
45 | 46 |
from authentic2.utils import views as utils_views |
46 | 47 |
from authentic2.utils.crypto import check_hmac_url, hash_chain, hmac_url |
src/authentic2_auth_oidc/backends.py | ||
---|---|---|
26 | 26 |
from jwcrypto.jwk import JWK |
27 | 27 |
from jwcrypto.jwt import JWT |
28 | 28 | |
29 |
from authentic2 import app_settings, hooks
|
|
29 |
from authentic2 import app_settings |
|
30 | 30 |
from authentic2.a2_rbac.models import OrganizationalUnit |
31 | 31 |
from authentic2.models import Lock |
32 |
from authentic2.utils import hooks |
|
32 | 33 |
from authentic2.utils.crypto import base64url_encode |
33 | 34 |
from authentic2.utils.template import Template |
34 | 35 |
src/authentic2_idp_cas/views.py | ||
---|---|---|
25 | 25 |
from django.utils.timezone import now |
26 | 26 |
from django.views.generic.base import View |
27 | 27 | |
28 |
from authentic2 import hooks |
|
29 | 28 |
from authentic2.attributes_ng.engine import get_attributes |
30 | 29 |
from authentic2.constants import NONCE_FIELD_NAME |
30 |
from authentic2.utils import hooks |
|
31 | 31 |
from authentic2.utils.misc import ( |
32 | 32 |
attribute_values_to_identifier, |
33 | 33 |
find_authentication_event, |
src/authentic2_idp_oidc/utils.py | ||
---|---|---|
27 | 27 |
from jwcrypto.jwk import JWK, InvalidJWKValue, JWKSet |
28 | 28 |
from jwcrypto.jwt import JWT |
29 | 29 | |
30 |
from authentic2 import hooks |
|
31 | 30 |
from authentic2.attributes_ng.engine import get_attributes |
32 |
from authentic2.utils import crypto |
|
31 |
from authentic2.utils import crypto, hooks
|
|
33 | 32 |
from authentic2.utils.misc import make_url |
34 | 33 |
from authentic2.utils.template import Template |
35 | 34 |
src/authentic2_idp_oidc/views.py | ||
---|---|---|
36 | 36 |
from ratelimit.utils import is_ratelimited |
37 | 37 | |
38 | 38 |
from authentic2 import app_settings as a2_app_settings |
39 |
from authentic2 import hooks |
|
40 | 39 |
from authentic2.a2_rbac.models import OrganizationalUnit |
41 | 40 |
from authentic2.custom_user.models import Profile |
42 | 41 |
from authentic2.decorators import setting_enabled |
43 | 42 |
from authentic2.exponential_retry_timeout import ExponentialRetryTimeout |
43 |
from authentic2.utils import hooks |
|
44 | 44 |
from authentic2.utils.misc import last_authentication_event, login_require, make_url, redirect |
45 | 45 |
from authentic2.utils.service import set_service |
46 | 46 |
from authentic2.utils.view_decorators import check_view_restriction |
tests/conftest.py | ||
---|---|---|
28 | 28 |
from django.db import connection, transaction |
29 | 29 |
from django.db.migrations.executor import MigrationExecutor |
30 | 30 | |
31 |
from authentic2 import hooks as a2_hooks |
|
32 | 31 |
from authentic2.a2_rbac.models import OrganizationalUnit, Role |
33 | 32 |
from authentic2.a2_rbac.utils import get_default_ou |
34 | 33 |
from authentic2.authentication import OIDCUser |
35 | 34 |
from authentic2.manager.utils import get_ou_count |
36 | 35 |
from authentic2.models import Attribute, Service |
36 |
from authentic2.utils import hooks as a2_hooks |
|
37 | 37 |
from authentic2.utils.evaluate import BaseExpressionValidator |
38 | 38 |
from authentic2_auth_oidc.utils import get_provider_by_issuer |
39 | 39 |
from authentic2_idp_oidc.models import OIDCClient |
tests/idp_oidc/test_user_profiles.py | ||
---|---|---|
437 | 437 | |
438 | 438 |
token_url = make_url('oidc-token') |
439 | 439 | |
440 |
with mock.patch('authentic2.hooks.get_hooks') as get_hooks: |
|
440 |
with mock.patch('authentic2.utils.hooks.get_hooks') as get_hooks:
|
|
441 | 441 |
get_hooks.return_value = mock_get_hooks('') |
442 | 442 |
response = app.post( |
443 | 443 |
token_url, |
444 |
- |