def revoke(self, path, name): fingerprint = self.log.get_key(name).fingerprint keypaths = self.get_keys(path)[fingerprint] if not keypaths: raise KeyError("%s fingerprint not present on %s" % (fingerprint, path)) # Revoke key from keypaths for path in keypaths: parent = self.get(path).perm ret = self.do_action(parent, self.log.revoke, path, name) # Get Higher paths selected = set() for path in keypaths: path = os.path.dirname(path) # remove .keys for spath in selected: if issubdir(path, spath): selected.remove(spath) selected.add(path) if path not in selected: selected.add(path) # Confirm valid state for all affected nodes for path in selected: node = self.get(path) self.rec_maintain_current_state(node, fingerprint) return ret
def update_granted_paths(self, path, keys): for fingerprint, key in keys.items(): if fingerprint in self.keys: try: granted_paths = self.granted_paths[fingerprint] except KeyError: granted_paths = set() self.granted_paths[fingerprint] = granted_paths for granted_path in granted_paths: if issubdir(path, granted_path): granted_paths.remove(granted_path) granted_paths.add(path) break else: granted_paths.add(path)
def get_key(self, path): """ path is granted by any self.keys """ path = os.path.normpath(path) selected = None selected_min_path = sys.maxsize for fingerprint, granted_paths in self.granted_paths.items(): min_path = sys.maxsize for granted_path in granted_paths: if granted_path == '/': return self.keys[fingerprint] elif issubdir(path, granted_path): min_path = min(min_path, granted_path.count(os.sep)) if min_path < selected_min_path: selected = fingerprint selected_min_path = min_path if selected: return self.keys[selected] return None
def get_keys(self, path='/', by_dir=False): result = defaultdict(set) for npath, node in self.paths.items(): if node.perm and issubdir(npath, path): branch = [] # FIXME access to log entries instead of view nodes? parent = node.perm while parent.is_permission: branch.insert(0, parent) parent = parent.parent keys = {} for node in branch: key = node.entry.read_key() if node.entry.action == node.entry.REVOKE: keys.pop(key.fingerprint) else: keys[key.fingerprint] = key for fingerprint, key in keys.items(): if by_dir: result[npath].add(fingerprint) else: result[fingerprint].add(npath) return result