Statistics
| Branch: | Tag: | Revision:

root / pithos / backends / lib / sqlite / permissions.py @ 5e068361

History | View | Annotate | Download (5.3 kB)

1 2e662088 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 a9b3f29d Antony Chazapis
# 
3 a9b3f29d Antony Chazapis
# Redistribution and use in source and binary forms, with or
4 a9b3f29d Antony Chazapis
# without modification, are permitted provided that the following
5 a9b3f29d Antony Chazapis
# conditions are met:
6 a9b3f29d Antony Chazapis
# 
7 a9b3f29d Antony Chazapis
#   1. Redistributions of source code must retain the above
8 a9b3f29d Antony Chazapis
#      copyright notice, this list of conditions and the following
9 a9b3f29d Antony Chazapis
#      disclaimer.
10 a9b3f29d Antony Chazapis
# 
11 a9b3f29d Antony Chazapis
#   2. Redistributions in binary form must reproduce the above
12 a9b3f29d Antony Chazapis
#      copyright notice, this list of conditions and the following
13 a9b3f29d Antony Chazapis
#      disclaimer in the documentation and/or other materials
14 a9b3f29d Antony Chazapis
#      provided with the distribution.
15 a9b3f29d Antony Chazapis
# 
16 a9b3f29d Antony Chazapis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 a9b3f29d Antony Chazapis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 a9b3f29d Antony Chazapis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 a9b3f29d Antony Chazapis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 a9b3f29d Antony Chazapis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 a9b3f29d Antony Chazapis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 a9b3f29d Antony Chazapis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 a9b3f29d Antony Chazapis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 a9b3f29d Antony Chazapis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 a9b3f29d Antony Chazapis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 a9b3f29d Antony Chazapis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 a9b3f29d Antony Chazapis
# POSSIBILITY OF SUCH DAMAGE.
28 a9b3f29d Antony Chazapis
# 
29 a9b3f29d Antony Chazapis
# The views and conclusions contained in the software and
30 a9b3f29d Antony Chazapis
# documentation are those of the authors and should not be
31 a9b3f29d Antony Chazapis
# interpreted as representing official policies, either expressed
32 a9b3f29d Antony Chazapis
# or implied, of GRNET S.A.
33 a9b3f29d Antony Chazapis
34 a9b3f29d Antony Chazapis
from xfeatures import XFeatures
35 a9b3f29d Antony Chazapis
from groups import Groups
36 a9b3f29d Antony Chazapis
from public import Public
37 a9b3f29d Antony Chazapis
38 a9b3f29d Antony Chazapis
39 6f4bce7b Antony Chazapis
READ = 0
40 6f4bce7b Antony Chazapis
WRITE = 1
41 6f4bce7b Antony Chazapis
42 6f4bce7b Antony Chazapis
43 a9b3f29d Antony Chazapis
class Permissions(XFeatures, Groups, Public):
44 a9b3f29d Antony Chazapis
    
45 a9b3f29d Antony Chazapis
    def __init__(self, **params):
46 a9b3f29d Antony Chazapis
        XFeatures.__init__(self, **params)
47 a9b3f29d Antony Chazapis
        Groups.__init__(self, **params)
48 a9b3f29d Antony Chazapis
        Public.__init__(self, **params)
49 a9b3f29d Antony Chazapis
    
50 6f4bce7b Antony Chazapis
    def access_grant(self, path, access, members=()):
51 0f9d752c Antony Chazapis
        """Grant members with access to path.
52 0f9d752c Antony Chazapis
           Members can also be '*' (all),
53 0f9d752c Antony Chazapis
           or some group specified as 'owner:group'."""
54 6f4bce7b Antony Chazapis
        
55 0f9d752c Antony Chazapis
        if not members:
56 0f9d752c Antony Chazapis
            return
57 6f4bce7b Antony Chazapis
        feature = self.xfeature_create(path)
58 6f4bce7b Antony Chazapis
        self.feature_setmany(feature, access, members)
59 6f4bce7b Antony Chazapis
    
60 0f9d752c Antony Chazapis
    def access_set(self, path, permissions):
61 0f9d752c Antony Chazapis
        """Set permissions for path. The permissions dict
62 0f9d752c Antony Chazapis
           maps 'read', 'write' keys to member lists."""
63 0f9d752c Antony Chazapis
        
64 5e068361 Antony Chazapis
        r = permissions.get('read', [])
65 5e068361 Antony Chazapis
        w = permissions.get('write', [])
66 5e068361 Antony Chazapis
        if not r and not w:
67 5e068361 Antony Chazapis
            self.xfeature_destroy(path)
68 5e068361 Antony Chazapis
            return
69 5e068361 Antony Chazapis
        feature = self.xfeature_create(path)
70 5e068361 Antony Chazapis
        self.feature_clear(feature)
71 5e068361 Antony Chazapis
        if r:
72 5e068361 Antony Chazapis
            self.feature_setmany(feature, READ, r)
73 5e068361 Antony Chazapis
        if w:
74 5e068361 Antony Chazapis
            self.feature_setmany(feature, WRITE, w)
75 0f9d752c Antony Chazapis
    
76 0f9d752c Antony Chazapis
    def access_clear(self, path):
77 0f9d752c Antony Chazapis
        """Revoke access to path (both permissions and public)."""
78 6f4bce7b Antony Chazapis
        
79 6f4bce7b Antony Chazapis
        self.xfeature_destroy(path)
80 0f9d752c Antony Chazapis
        self.public_unset(path)
81 6f4bce7b Antony Chazapis
    
82 6f4bce7b Antony Chazapis
    def access_check(self, path, access, member):
83 a9b3f29d Antony Chazapis
        """Return true if the member has this access to the path."""
84 6f4bce7b Antony Chazapis
        
85 bb4eafc6 Antony Chazapis
        if access == READ and self.public_get(path) is not None:
86 6f4bce7b Antony Chazapis
            return True
87 6f4bce7b Antony Chazapis
        
88 43763394 Antony Chazapis
        feature = self.xfeature_get(path)
89 43763394 Antony Chazapis
        if not feature:
90 6f4bce7b Antony Chazapis
            return False
91 6f4bce7b Antony Chazapis
        members = self.feature_get(feature, access)
92 6f4bce7b Antony Chazapis
        if member in members or '*' in members:
93 6f4bce7b Antony Chazapis
            return True
94 62f915a1 Antony Chazapis
        for owner, group in self.group_parents(member):
95 6f4bce7b Antony Chazapis
            if owner + ':' + group in members:
96 6f4bce7b Antony Chazapis
                return True
97 676edf89 Antony Chazapis
        return False
98 6f4bce7b Antony Chazapis
    
99 6f4bce7b Antony Chazapis
    def access_inherit(self, path):
100 43763394 Antony Chazapis
        """Return the paths influencing the access for path."""
101 6f4bce7b Antony Chazapis
        
102 a9b3f29d Antony Chazapis
        r = self.xfeature_inherit(path)
103 a9b3f29d Antony Chazapis
        if not r:
104 43763394 Antony Chazapis
            return []
105 43763394 Antony Chazapis
        
106 43763394 Antony Chazapis
        def get_permissions(feature):
107 43763394 Antony Chazapis
            permissions = self.feature_dict(feature)
108 43763394 Antony Chazapis
            if READ in permissions:
109 43763394 Antony Chazapis
                permissions['read'] = permissions[READ]
110 43763394 Antony Chazapis
                del(permissions[READ])
111 43763394 Antony Chazapis
            if WRITE in permissions:
112 43763394 Antony Chazapis
                permissions['write'] = permissions[WRITE]
113 43763394 Antony Chazapis
                del(permissions[WRITE])
114 43763394 Antony Chazapis
            return permissions
115 6f4bce7b Antony Chazapis
        
116 43763394 Antony Chazapis
        # Only keep path components.
117 43763394 Antony Chazapis
        parts = path.rstrip('/').split('/')
118 43763394 Antony Chazapis
        valid = []
119 43763394 Antony Chazapis
        for i in range(1, len(parts)):
120 43763394 Antony Chazapis
            subp = '/'.join(parts[:i + 1])
121 43763394 Antony Chazapis
            valid.append(subp)
122 43763394 Antony Chazapis
            valid.append(subp + '/')
123 43763394 Antony Chazapis
        return [(x[0], get_permissions(x[1])) for x in r if x[0] in valid]
124 6f4bce7b Antony Chazapis
    
125 6f4bce7b Antony Chazapis
    def access_list_paths(self, member, prefix=None):
126 6f4bce7b Antony Chazapis
        """Return the list of paths granted to member."""
127 6f4bce7b Antony Chazapis
        
128 6f4bce7b Antony Chazapis
        q = ("select distinct path from xfeatures inner join "
129 6f4bce7b Antony Chazapis
             "   (select distinct feature_id, key from xfeaturevals inner join "
130 0f9d752c Antony Chazapis
             "      (select owner || ':' || name as value from groups "
131 7f9d881d Antony Chazapis
             "       where member = ? union select ? union select '*') "
132 a9b3f29d Antony Chazapis
             "    using (value)) "
133 6f4bce7b Antony Chazapis
             "using (feature_id)")
134 6f4bce7b Antony Chazapis
        p = (member, member)
135 6f4bce7b Antony Chazapis
        if prefix:
136 7759260d Antony Chazapis
            q += " where path like ? escape '\\'"
137 7759260d Antony Chazapis
            p += (self.escape_like(prefix) + '%',)
138 6f4bce7b Antony Chazapis
        self.execute(q, p)
139 6f4bce7b Antony Chazapis
        return [r[0] for r in self.fetchall()]
140 6f4bce7b Antony Chazapis
    
141 6f4bce7b Antony Chazapis
    def access_list_shared(self, prefix=''):
142 6f4bce7b Antony Chazapis
        """Return the list of shared paths."""
143 6f4bce7b Antony Chazapis
        
144 7759260d Antony Chazapis
        q = "select path from xfeatures where path like ? escape '\\'"
145 7759260d Antony Chazapis
        self.execute(q, (self.escape_like(prefix) + '%',))
146 6f4bce7b Antony Chazapis
        return [r[0] for r in self.fetchall()]