24a79c800922360680c6a55482669f6451d6759c
[pithos] / pithos / backends / lib / permissions.py
1 # Copyright 2011 GRNET S.A. All rights reserved.
2
3 # Redistribution and use in source and binary forms, with or
4 # without modification, are permitted provided that the following
5 # conditions are met:
6
7 #   1. Redistributions of source code must retain the above
8 #      copyright notice, this list of conditions and the following
9 #      disclaimer.
10
11 #   2. Redistributions in binary form must reproduce the above
12 #      copyright notice, this list of conditions and the following
13 #      disclaimer in the documentation and/or other materials
14 #      provided with the distribution.
15
16 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
28
29 # The views and conclusions contained in the software and
30 # documentation are those of the authors and should not be
31 # interpreted as representing official policies, either expressed
32 # or implied, of GRNET S.A.
33
34 from xfeatures import XFeatures
35 from groups import Groups
36 from public import Public
37
38
39 class Permissions(XFeatures, Groups, Public):
40     
41     def __init__(self, **params):
42         XFeatures.__init__(self, **params)
43         Groups.__init__(self, **params)
44         Public.__init__(self, **params)
45     
46     def access_grant(self, access, path, member='all', members=()):
47         """Grant a member with an access to a path."""
48         xfeatures = self.xfeature_list(path)
49         xfl = len(xfeatures)
50         if xfl > 1 or (xfl == 1 and xfeatures[0][0] != path):
51             return xfeatures
52         if xfl == 0:
53             feature = self.alloc_serial()
54             self.xfeature_bestow(path, feature)
55         else:
56             fpath, feature = xfeatures[0]
57
58         if members:
59             self.feature_setmany(feature, access, members)
60         else:
61             self.feature_set(feature, access, member)
62
63         return ()
64
65     def access_revoke(self, access, path, member='all', members=()):
66         """Revoke access to path from members.
67            Note that this will not revoke access for members
68            that are indirectly granted access through group membership.
69         """
70         # XXX: Maybe provide a force_revoke that will kick out
71         #      all groups containing the given members?
72         xfeatures = self.xfeature_list(path)
73         xfl = len(xfeatures)
74         if xfl != 1 or xfeatures[0][0] != path:
75             return xfeatures
76
77         fpath, feature = xfeatures[0]
78
79         if members:
80             self.feature_unsetmany(feature, access, members=members)
81         else:
82             self.feature_unset(feature, access, member)
83
84         # XXX: provide a meaningful return value? 
85
86         return ()
87
88     def access_check(self, access, path, member):
89         """Return true if the member has this access to the path."""
90         r = self.xfeature_inherit(path)
91         if not r:
92             return 0
93
94         fpath, feature = r
95         memberset = set(self.feature_get(feature, access))
96         if member in memberset:
97             return 1
98
99         for group in self.group_parents(self, member):
100             if group in memberset:
101                 return 1
102
103         return 0
104
105     def access_list(self, path):
106         """Return the list of (access, member) pairs for the path."""
107         r = self.xfeature_inherit(path)
108         if not r:
109             return ()
110
111         fpath, feature = r
112         return self.feature_list(feature)
113
114     def access_list_paths(self, member):
115         """Return the list of (access, path) pairs granted to member."""
116         q = ("select distinct key, path from xfeatures inner join "
117              "   (select distinct feature, key from xfeaturevals inner join "
118              "      (select name as value from members "
119              "       where member = ? union select ?) "
120              "    using (value)) "
121              "using (feature)")
122
123         self.execute(q, (member, member))
124         return self.fetchall()