hooks/security.py
author Julien Cristau <julien.cristau@logilab.fr>
Mon, 18 May 2015 20:00:06 +0200
changeset 10436 6493c8bf521d
parent 10388 90fcddcce166
child 10547 a05a698a12af
permissions -rw-r--r--
[test] don't leave NULL columns around when making an attribute required It doesn't matter on sqlite (it doesn't do ALTER COLUMN), but when running this test on postgresql it fails to add the 'NOT NULL' constraint otherwise.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9981
7099bbd685aa [hooks/security] allow edition of attributes with permissive permissions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9536
diff changeset
     1
# copyright 2003-2014 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
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
__docformat__ = "restructuredtext en"
9395
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    23
from warnings import warn
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
    25
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
    26
9129
6c4ae3a06619 [hooks/security] Streamline attributes default permission check.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
    27
from yams import buildobjs
6c4ae3a06619 [hooks/security] Streamline attributes default permission check.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
    28
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
from cubicweb import Unauthorized
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
    30
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
    31
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
9395
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    33
9612
24460d4d64bf [hooks/security] let's use a connection, not a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
    34
def check_entity_attributes(cnx, entity, action, editedattrs=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
    eid = entity.eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
    eschema = entity.e_schema
9981
7099bbd685aa [hooks/security] allow edition of attributes with permissive permissions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9536
diff changeset
    37
    if action == 'delete':
7099bbd685aa [hooks/security] allow edition of attributes with permissive permissions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9536
diff changeset
    38
        eschema.check_perm(session, action, eid=eid)
7099bbd685aa [hooks/security] allow edition of attributes with permissive permissions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9536
diff changeset
    39
        return
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5449
diff changeset
    40
    # ._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
    41
    # 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
    42
    if editedattrs is None:
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
    43
        editedattrs = entity.cw_edited
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
    44
    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
    45
    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
    46
    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
    47
        if attr in dontcheck:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
            continue
9521
9eb810333b0f [hooks/security, devtools/fill] silence yams 0.38.0 warnings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9129
diff changeset
    49
        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
    50
        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
    51
            perms = rdef.permissions.get(action)
9129
6c4ae3a06619 [hooks/security] Streamline attributes default permission check.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
    52
            # 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
    53
            #
9395
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    54
            #  ('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
    55
            #                              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
    56
            #
6c4ae3a06619 [hooks/security] Streamline attributes default permission check.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
    57
            # 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
    58
            # implements comparison by rql expression.
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    59
            if perms == buildobjs.DEFAULT_ATTRPERMS[action]:
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    60
                # 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
    61
                # 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
    62
                if not etypechecked:
7099bbd685aa [hooks/security] allow edition of attributes with permissive permissions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9536
diff changeset
    63
                    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
    64
                    etypechecked = True
9129
6c4ae3a06619 [hooks/security] Streamline attributes default permission check.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
    65
                continue
9395
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    66
            if perms == ():
9412
8aa6c923d6c0 [security] Add comment to check_entity_attributes shortcut
Julien Cristau <julien.cristau@logilab.fr>
parents: 9395
diff changeset
    67
                # 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
    68
                # going through check_perm.
9395
96dba2efd16d [hooks/security] provide attribute "add" permission
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9254
diff changeset
    69
                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
    70
            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
    71
10153
85cbf16fbb57 [security] Test case and fix for an INSERT security hole
Julien Cristau <julien.cristau@logilab.fr>
parents: 9981
diff changeset
    72
    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
    73
        # 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
    74
        # 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
    75
        # 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
    76
        # 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
    77
        entity.cw_check_perm(action)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    78
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    79
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
    80
class CheckEntityPermissionOp(hook.DataOperationMixIn, hook.LateOperation):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
    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
    82
        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
    83
        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
    84
            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
    85
            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
    86
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    87
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
    88
class CheckRelationPermissionOp(hook.DataOperationMixIn, hook.LateOperation):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
    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
    90
        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
    91
        for action, rschema, eidfrom, eidto 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
    92
            rdef = rschema.rdef(cnx.entity_metas(eidfrom)['type'],
24460d4d64bf [hooks/security] let's use a connection, not a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
    93
                                cnx.entity_metas(eidto)['type'])
24460d4d64bf [hooks/security] let's use a connection, not a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
    94
            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
    95
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
    96
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
    97
@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
    98
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
    99
    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
   100
        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
   101
    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
   102
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   103
class SecurityHook(hook.Hook):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   104
    __abstract__ = True
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   105
    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
   106
    __select__ = hook.Hook.__select__ & write_security_enabled()
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   107
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   109
class AfterAddEntitySecurityHook(SecurityHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   110
    __regid__ = 'securityafteraddentity'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   111
    events = ('after_add_entity',)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   112
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   113
    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
   114
        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
   115
            (self.entity.eid, 'add', self.entity.cw_edited) )
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   116
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   117
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   118
class AfterUpdateEntitySecurityHook(SecurityHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   119
    __regid__ = 'securityafterupdateentity'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   120
    events = ('after_update_entity',)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   121
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   122
    def __call__(self):
9254
e1369f2dba79 [hooks/security] Defer entity permission checks to an Operation.
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9129
diff changeset
   123
        # 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
   124
        # 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
   125
        # 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
   126
        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
   127
        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
   128
            (self.entity.eid, action, self.entity.cw_edited) )
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   131
class BeforeDelEntitySecurityHook(SecurityHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   132
    __regid__ = 'securitybeforedelentity'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   133
    events = ('before_delete_entity',)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   134
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   135
    def __call__(self):
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5449
diff changeset
   136
        self.entity.cw_check_perm('delete')
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   137
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
   138
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
   139
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
   140
    """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
   141
    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
   142
    `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
   143
    """
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
   144
    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
   145
    try:
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
        entity = cnx.transaction_data['ecache'][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
   147
    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
   148
        return False
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
   149
    return rschema.type in entity.cw_edited.skip_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
   150
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
   151
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   152
class BeforeAddRelationSecurityHook(SecurityHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   153
    __regid__ = 'securitybeforeaddrelation'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   154
    events = ('before_add_relation',)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   155
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   156
    def __call__(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   157
        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
   158
            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
   159
            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
   160
                return
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   161
            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
   162
            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
   163
                    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
   164
                return
9469
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9395
diff changeset
   165
            rdef = rschema.rdef(self._cw.entity_metas(self.eidfrom)['type'],
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9395
diff changeset
   166
                                self._cw.entity_metas(self.eidto)['type'])
4190
742e3eb16f81 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4048
diff changeset
   167
            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
   168
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
class AfterAddRelationSecurityHook(SecurityHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   171
    __regid__ = 'securityafteraddrelation'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   172
    events = ('after_add_relation',)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   174
    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
   175
        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
   176
            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
   177
            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
   178
                return
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   179
            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
   180
            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
   181
                    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
   182
                return
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   183
            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
   184
                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
   185
                    ('add', rschema, self.eidfrom, self.eidto) )
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   186
            else:
9469
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9395
diff changeset
   187
                rdef = rschema.rdef(self._cw.entity_metas(self.eidfrom)['type'],
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9395
diff changeset
   188
                                    self._cw.entity_metas(self.eidto)['type'])
4003
b9436fe77c9e fix bad merge
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3890
diff changeset
   189
                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
   190
4048
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
class BeforeDeleteRelationSecurityHook(SecurityHook):
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   193
    __regid__ = 'securitybeforedelrelation'
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   194
    events = ('before_delete_relation',)
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   195
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   196
    def __call__(self):
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   197
        nocheck = self._cw.transaction_data.get('skip-security', ())
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   198
        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
   199
            return
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   200
        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
   201
        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
   202
                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
   203
            return
9469
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9395
diff changeset
   204
        rdef = rschema.rdef(self._cw.entity_metas(self.eidfrom)['type'],
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9395
diff changeset
   205
                            self._cw.entity_metas(self.eidto)['type'])
4190
742e3eb16f81 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4048
diff changeset
   206
        rdef.check_perm(self._cw, 'delete', fromeid=self.eidfrom, toeid=self.eidto)
4048
12c4f7e2bed6 had been involontarly dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
   207