Statistics
| Branch: | Tag: | Revision:

root / pithos / backends / lib / sqlalchemy / permissions.py @ 371d907a

History | View | Annotate | Download (6 kB)

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