source: trunk/src/allmydata/blacklist.py

Last change on this file was 1cfe843d, checked in by Alexandre Detiste <alexandre.detiste@…>, at 2024-02-22T23:40:25Z

more python2 removal

  • Property mode set to 100644
File size: 4.8 KB
Line 
1"""
2Ported to Python 3.
3"""
4
5import os
6
7from zope.interface import implementer
8from twisted.internet import defer
9from twisted.python import log as twisted_log
10
11from allmydata.interfaces import IFileNode, IFilesystemNode
12from allmydata.util import base32
13from allmydata.util.encodingutil import quote_output
14
15
16class FileProhibited(Exception):
17    """This client has been configured to prohibit access to this object."""
18    def __init__(self, reason):
19        Exception.__init__(self, "Access Prohibited: %s" % quote_output(reason, encoding='utf-8', quotemarks=False))
20        self.reason = reason
21
22
23class Blacklist(object):
24    def __init__(self, blacklist_fn):
25        self.blacklist_fn = blacklist_fn
26        self.last_mtime = None
27        self.entries = {}
28        self.read_blacklist() # sets .last_mtime and .entries
29
30    def read_blacklist(self):
31        try:
32            current_mtime = os.stat(self.blacklist_fn).st_mtime
33        except EnvironmentError:
34            # unreadable blacklist file means no blacklist
35            self.entries.clear()
36            return
37        try:
38            if self.last_mtime is None or current_mtime > self.last_mtime:
39                self.entries.clear()
40                with open(self.blacklist_fn, "rb") as f:
41                    for line in f:
42                        line = line.strip()
43                        if not line or line.startswith(b"#"):
44                            continue
45                        si_s, reason = line.split(None, 1)
46                        si = base32.a2b(si_s) # must be valid base32
47                        self.entries[si] = reason
48                self.last_mtime = current_mtime
49        except Exception as e:
50            twisted_log.err(e, "unparseable blacklist file")
51            raise
52
53    def check_storageindex(self, si):
54        self.read_blacklist()
55        reason = self.entries.get(si, None)
56        if reason is not None:
57            # log this to logs/twistd.log, since web logs go there too
58            twisted_log.msg("blacklist prohibited access to SI %r: %r" %
59                            (base32.b2a(si), reason))
60        return reason
61
62
63@implementer(IFileNode)
64class ProhibitedNode(object):
65
66    def __init__(self, wrapped_node, reason):
67        assert IFilesystemNode.providedBy(wrapped_node), wrapped_node
68        self.wrapped_node = wrapped_node
69        self.reason = reason
70
71    def get_cap(self):
72        return self.wrapped_node.get_cap()
73
74    def get_readcap(self):
75        return self.wrapped_node.get_readcap()
76
77    def is_readonly(self):
78        return self.wrapped_node.is_readonly()
79
80    def is_mutable(self):
81        return self.wrapped_node.is_mutable()
82
83    def is_unknown(self):
84        return self.wrapped_node.is_unknown()
85
86    def is_allowed_in_immutable_directory(self):
87        return self.wrapped_node.is_allowed_in_immutable_directory()
88
89    def is_alleged_immutable(self):
90        return self.wrapped_node.is_alleged_immutable()
91
92    def raise_error(self):
93        # We don't raise an exception here because that would prevent the node from being listed.
94        pass
95
96    def get_uri(self):
97        return self.wrapped_node.get_uri()
98
99    def get_write_uri(self):
100        return self.wrapped_node.get_write_uri()
101
102    def get_readonly_uri(self):
103        return self.wrapped_node.get_readonly_uri()
104
105    def get_storage_index(self):
106        return self.wrapped_node.get_storage_index()
107
108    def get_verify_cap(self):
109        return self.wrapped_node.get_verify_cap()
110
111    def get_repair_cap(self):
112        return self.wrapped_node.get_repair_cap()
113
114    def get_size(self):
115        return None
116
117    def get_current_size(self):
118        return defer.succeed(None)
119
120    def get_size_of_best_version(self):
121        return defer.succeed(None)
122
123    def check(self, monitor, verify, add_lease):
124        return defer.succeed(None)
125
126    def check_and_repair(self, monitor, verify, add_lease):
127        return defer.succeed(None)
128
129    def get_version(self):
130        return None
131
132    # Omitting any of these methods would fail safe; they are just to ensure correct error reporting.
133
134    def get_best_readable_version(self):
135        raise FileProhibited(self.reason)
136
137    def download_best_version(self):
138        raise FileProhibited(self.reason)
139
140    def get_best_mutable_version(self):
141        raise FileProhibited(self.reason)
142
143    def overwrite(self, new_contents):
144        raise FileProhibited(self.reason)
145
146    def modify(self, modifier_cb):
147        raise FileProhibited(self.reason)
148
149    def get_servermap(self, mode):
150        raise FileProhibited(self.reason)
151
152    def download_version(self, servermap, version):
153        raise FileProhibited(self.reason)
154
155    def upload(self, new_contents, servermap):
156        raise FileProhibited(self.reason)
157
158    def get_writekey(self):
159        raise FileProhibited(self.reason)
160
161    def read(self, consumer, offset=0, size=None):
162        raise FileProhibited(self.reason)
Note: See TracBrowser for help on using the repository browser.