cubicweb/hooks/security.py
author Philippe Pepiot <ph@itsalwaysdns.eu>
Tue, 31 Mar 2020 18:22:05 +0200
changeset 12966 6cd938c29ca3
parent 11767 432f87a63057
permissions -rw-r--r--
[server] Make connection pooler configurable and set better default values Drop the configuration connections-pool-size and add new configurations options: * connections-pool-min-size. Set to 0 by default so we open connections only when needed. This avoid opening min-size*processes connections at startup, which is, it think, a good default. * connections-pool-max-size. Set to 0 (unlimited) by default, so we move the bottleneck to postgresql. * connections-idle-timeout. Set to 10 minutes. I don't have arguments about this except that this is the default in pgbouncer.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11765
diff changeset
     1
# copyright 2003-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4999
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
"""Security hooks: check permissions to add/delete/update entities according to
9612
24460d4d64bf [hooks/security] let's use a connection, not a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
    19
the connected user
5813
0b250d72fcfa [transaction w/ separated web/repo processes] the dbapi should explicitly specify a transaction id to avoid confusion when web server / repository run in separated processes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5670
diff changeset
    20
"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
    22
from logilab.common.registry import objectify_predicate
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
    23
9129
6c4ae3a06619 [hooks/security] Streamline attributes default permission check.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
    24
from yams import buildobjs
6c4ae3a06619 [hooks/security] Streamline attributes default permission check.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
    25
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
from cubicweb import Unauthorized
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
    27
from cubicweb.server import BEFORE_ADD_RELATIONS, ON_COMMIT_ADD_RELATIONS, hook
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
    28
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
9612
24460d4d64bf [hooks/security] let's use a connection, not a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
    30
def check_entity_attributes(cnx, entity, action, editedattrs=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
    eid = entity.eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
    eschema = entity.e_schema
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5449
diff changeset
    33
    # ._cw_skip_security_attributes is there to bypass security for attributes
8238
087bb529035c [spelling] fix dictionnary -> dictionary typo
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
    34
    # set by hooks by modifying the entity's dictionary
4577
049d92fc8614 [security] we should save back edited_attributes in case of multiple modification of an entity during the same transaction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
    35
    if editedattrs is None:
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
    36
        editedattrs = entity.cw_edited
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
    37
    dontcheck = editedattrs.skip_security
9981
7099bbd685aa [hooks/security] allow edition of attributes with permissive permissions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9536
diff changeset
    38
    etypechecked = False
2647
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    39
    for attr in editedattrs:
4999
221f76e14eea don't update dontcheck until everything went fine:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4970
diff changeset
    40
        if attr in dontcheck:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
            continue
9521
9eb810333b0f [hooks/security, devtools/fill] silence yams 0.38.0 warnings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9129
diff changeset
    42
        rdef = eschema.rdef(attr, takefirst=True)
9129
6c4ae3a06619 [hooks/security] Streamline attributes default permission check.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
    43
        if rdef.final: # non final relation are checked by standard hooks
9395
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    44
            perms = rdef.permissions.get(action)
9129
6c4ae3a06619 [hooks/security] Streamline attributes default permission check.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
    45
            # comparison below works because the default update perm is:
6c4ae3a06619 [hooks/security] Streamline attributes default permission check.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
    46
            #
9395
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    47
            #  ('managers', ERQLExpression(Any X WHERE U has_update_permission X,
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    48
            #                              X eid %(x)s, U eid %(u)s))
9129
6c4ae3a06619 [hooks/security] Streamline attributes default permission check.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
    49
            #
6c4ae3a06619 [hooks/security] Streamline attributes default permission check.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
    50
            # is deserialized in this order (groups first), and ERQLExpression
9395
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    51
            # implements comparison by rql expression.
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    52
            if perms == buildobjs.DEFAULT_ATTRPERMS[action]:
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    53
                # The default rule is to delegate to the entity
9981
7099bbd685aa [hooks/security] allow edition of attributes with permissive permissions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9536
diff changeset
    54
                # rule. This needs to be checked only once.
7099bbd685aa [hooks/security] allow edition of attributes with permissive permissions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9536
diff changeset
    55
                if not etypechecked:
7099bbd685aa [hooks/security] allow edition of attributes with permissive permissions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9536
diff changeset
    56
                    entity.cw_check_perm(action)
7099bbd685aa [hooks/security] allow edition of attributes with permissive permissions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9536
diff changeset
    57
                    etypechecked = True
9129
6c4ae3a06619 [hooks/security] Streamline attributes default permission check.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
    58
                continue
9395
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    59
            if perms == ():
9412
8aa6c923d6c0 [security] Add comment to check_entity_attributes shortcut
Julien Cristau <julien.cristau@logilab.fr>
parents: 9395
diff changeset
    60
                # That means an immutable attribute; as an optimization, avoid
8aa6c923d6c0 [security] Add comment to check_entity_attributes shortcut
Julien Cristau <julien.cristau@logilab.fr>
parents: 9395
diff changeset
    61
                # going through check_perm.
9395
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    62
                raise Unauthorized(action, str(rdef))
9612
24460d4d64bf [hooks/security] let's use a connection, not a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
    63
            rdef.check_perm(cnx, action, eid=eid)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    64
10153
85cbf16fbb57 [security] Test case and fix for an INSERT security hole
Julien Cristau <julien.cristau@logilab.fr>
parents: 9981
diff changeset
    65
    if action == 'add' and not etypechecked:
85cbf16fbb57 [security] Test case and fix for an INSERT security hole
Julien Cristau <julien.cristau@logilab.fr>
parents: 9981
diff changeset
    66
        # think about cnx.create_entity('Foo')
85cbf16fbb57 [security] Test case and fix for an INSERT security hole
Julien Cristau <julien.cristau@logilab.fr>
parents: 9981
diff changeset
    67
        # the standard metadata were inserted by a hook
85cbf16fbb57 [security] Test case and fix for an INSERT security hole
Julien Cristau <julien.cristau@logilab.fr>
parents: 9981
diff changeset
    68
        # with a bypass ... we conceptually need to check
85cbf16fbb57 [security] Test case and fix for an INSERT security hole
Julien Cristau <julien.cristau@logilab.fr>
parents: 9981
diff changeset
    69
        # the eid attribute at *creation* time
85cbf16fbb57 [security] Test case and fix for an INSERT security hole
Julien Cristau <julien.cristau@logilab.fr>
parents: 9981
diff changeset
    70
        entity.cw_check_perm(action)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    71
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    72
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    73
class CheckEntityPermissionOp(hook.DataOperationMixIn, hook.LateOperation):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
    def precommit_event(self):
9612
24460d4d64bf [hooks/security] let's use a connection, not a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
    75
        cnx = self.cnx
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    76
        for eid, action, edited in self.get_data():
9612
24460d4d64bf [hooks/security] let's use a connection, not a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
    77
            entity = cnx.entity_from_eid(eid)
24460d4d64bf [hooks/security] let's use a connection, not a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
    78
            check_entity_attributes(cnx, entity, action, edited)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    79
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    80
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    81
class CheckRelationPermissionOp(hook.DataOperationMixIn, hook.LateOperation):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
    def precommit_event(self):
9612
24460d4d64bf [hooks/security] let's use a connection, not a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
    83
        cnx = self.cnx
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    84
        for action, rschema, eidfrom, eidto in self.get_data():
11765
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    85
            rdef = rschema.rdef(cnx.entity_type(eidfrom),
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    86
                                cnx.entity_type(eidto))
9612
24460d4d64bf [hooks/security] let's use a connection, not a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
    87
            rdef.check_perm(cnx, action, fromeid=eidfrom, toeid=eidto)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    88
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
    89
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
    90
@objectify_predicate
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4577
diff changeset
    91
def write_security_enabled(cls, req, **kwargs):
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4577
diff changeset
    92
    if req is None or not req.write_security:
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4577
diff changeset
    93
        return 0
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4577
diff changeset
    94
    return 1
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4577
diff changeset
    95
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
    96
class SecurityHook(hook.Hook):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
    97
    __abstract__ = True
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
    98
    category = 'security'
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4577
diff changeset
    99
    __select__ = hook.Hook.__select__ & write_security_enabled()
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   100
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   102
class AfterAddEntitySecurityHook(SecurityHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   103
    __regid__ = 'securityafteraddentity'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   104
    events = ('after_add_entity',)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   105
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   106
    def __call__(self):
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   107
        CheckEntityPermissionOp.get_instance(self._cw).add_data(
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   108
            (self.entity.eid, 'add', self.entity.cw_edited) )
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   109
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   110
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   111
class AfterUpdateEntitySecurityHook(SecurityHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   112
    __regid__ = 'securityafterupdateentity'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   113
    events = ('after_update_entity',)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   114
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   115
    def __call__(self):
9254
e1369f2dba79 [hooks/security] Defer entity permission checks to an Operation.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9129
diff changeset
   116
        # save back editedattrs in case the entity is reedited later in the
e1369f2dba79 [hooks/security] Defer entity permission checks to an Operation.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9129
diff changeset
   117
        # same transaction, which will lead to cw_edited being
e1369f2dba79 [hooks/security] Defer entity permission checks to an Operation.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9129
diff changeset
   118
        # overwritten
10114
6f4b4567b77d [security] check attributes: dispatch on the "add" action if entity was just created
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9984
diff changeset
   119
        action = 'add' if self._cw.added_in_transaction(self.entity.eid) else 'update'
9254
e1369f2dba79 [hooks/security] Defer entity permission checks to an Operation.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9129
diff changeset
   120
        CheckEntityPermissionOp.get_instance(self._cw).add_data(
10114
6f4b4567b77d [security] check attributes: dispatch on the "add" action if entity was just created
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9984
diff changeset
   121
            (self.entity.eid, action, self.entity.cw_edited) )
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   124
class BeforeDelEntitySecurityHook(SecurityHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   125
    __regid__ = 'securitybeforedelentity'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   126
    events = ('before_delete_entity',)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   127
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   128
    def __call__(self):
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5449
diff changeset
   129
        self.entity.cw_check_perm('delete')
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   130
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
   131
10388
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   132
def skip_inlined_relation_security(cnx, rschema, eid):
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   133
    """return True if security for the given inlined relation should be skipped,
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   134
    in case where the relation has been set through modification of
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   135
    `entity.cw_edited` in a hook
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   136
    """
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   137
    assert rschema.inlined
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   138
    try:
10547
a05a698a12af [hook] don't open-code Connection.entity_cache
Julien Cristau <julien.cristau@logilab.fr>
parents: 10388
diff changeset
   139
        entity = cnx.entity_cache(eid)
10388
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   140
    except KeyError:
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   141
        return False
10548
2b398e58ea73 [hook] remove assumption about entity cache vs cw_edited
Julien Cristau <julien.cristau@logilab.fr>
parents: 10547
diff changeset
   142
    edited = getattr(entity, 'cw_edited', None)
2b398e58ea73 [hook] remove assumption about entity cache vs cw_edited
Julien Cristau <julien.cristau@logilab.fr>
parents: 10547
diff changeset
   143
    if edited is None:
2b398e58ea73 [hook] remove assumption about entity cache vs cw_edited
Julien Cristau <julien.cristau@logilab.fr>
parents: 10547
diff changeset
   144
        return False
2b398e58ea73 [hook] remove assumption about entity cache vs cw_edited
Julien Cristau <julien.cristau@logilab.fr>
parents: 10547
diff changeset
   145
    return rschema.type in edited.skip_security
10388
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   146
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   147
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   148
class BeforeAddRelationSecurityHook(SecurityHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   149
    __regid__ = 'securitybeforeaddrelation'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   150
    events = ('before_add_relation',)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   151
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   152
    def __call__(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   153
        if self.rtype in BEFORE_ADD_RELATIONS:
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920 2895
diff changeset
   154
            nocheck = self._cw.transaction_data.get('skip-security', ())
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920 2895
diff changeset
   155
            if (self.eidfrom, self.rtype, self.eidto) in nocheck:
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920 2895
diff changeset
   156
                return
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   157
            rschema = self._cw.repo.schema[self.rtype]
10388
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   158
            if rschema.inlined and skip_inlined_relation_security(
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   159
                    self._cw, rschema, self.eidfrom):
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   160
                return
11765
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   161
            rdef = rschema.rdef(self._cw.entity_type(self.eidfrom),
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   162
                                self._cw.entity_type(self.eidto))
4190
742e3eb16f81 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4048
diff changeset
   163
            rdef.check_perm(self._cw, 'add', fromeid=self.eidfrom, toeid=self.eidto)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   164
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   166
class AfterAddRelationSecurityHook(SecurityHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   167
    __regid__ = 'securityafteraddrelation'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   168
    events = ('after_add_relation',)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   170
    def __call__(self):
10388
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   171
        if self.rtype not in BEFORE_ADD_RELATIONS:
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920 2895
diff changeset
   172
            nocheck = self._cw.transaction_data.get('skip-security', ())
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920 2895
diff changeset
   173
            if (self.eidfrom, self.rtype, self.eidto) in nocheck:
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920 2895
diff changeset
   174
                return
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   175
            rschema = self._cw.repo.schema[self.rtype]
10388
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   176
            if rschema.inlined and skip_inlined_relation_security(
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   177
                    self._cw, rschema, self.eidfrom):
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   178
                return
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   179
            if self.rtype in ON_COMMIT_ADD_RELATIONS:
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   180
                CheckRelationPermissionOp.get_instance(self._cw).add_data(
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   181
                    ('add', rschema, self.eidfrom, self.eidto) )
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   182
            else:
11765
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   183
                rdef = rschema.rdef(self._cw.entity_type(self.eidfrom),
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   184
                                    self._cw.entity_type(self.eidto))
4003
b9436fe77c9e fix bad merge
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3890
diff changeset
   185
                rdef.check_perm(self._cw, 'add', fromeid=self.eidfrom, toeid=self.eidto)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   186
4048
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   187
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   188
class BeforeDeleteRelationSecurityHook(SecurityHook):
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   189
    __regid__ = 'securitybeforedelrelation'
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   190
    events = ('before_delete_relation',)
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   191
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   192
    def __call__(self):
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   193
        nocheck = self._cw.transaction_data.get('skip-security', ())
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   194
        if (self.eidfrom, self.rtype, self.eidto) in nocheck:
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   195
            return
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   196
        rschema = self._cw.repo.schema[self.rtype]
10388
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   197
        if rschema.inlined and skip_inlined_relation_security(
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   198
                self._cw, rschema, self.eidfrom):
90fcddcce166 when some inlined relation is set using cw_edited, its security shouldn't be checked.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10156
diff changeset
   199
            return
11765
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   200
        rdef = rschema.rdef(self._cw.entity_type(self.eidfrom),
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   201
                            self._cw.entity_type(self.eidto))
4190
742e3eb16f81 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4048
diff changeset
   202
        rdef.check_perm(self._cw, 'delete', fromeid=self.eidfrom, toeid=self.eidto)