264 |
264 |
|
265 |
265 |
self.lock_container_path = False
|
266 |
266 |
|
267 |
|
self.read_allowed = defaultdict(list)
|
268 |
|
self.write_allowed = defaultdict(list)
|
|
267 |
self.container_tuple = None
|
|
268 |
|
|
269 |
self._reset_allowed_paths()
|
269 |
270 |
|
270 |
|
def pre_exec(self, lock_container_path=False):
|
|
271 |
def pre_exec(self, user, account=None, container=None, name=None,
|
|
272 |
action='read', lock_container_path=False):
|
271 |
273 |
self.serials = []
|
272 |
274 |
self.messages = []
|
273 |
275 |
|
274 |
|
self.read_allowed = defaultdict(list)
|
275 |
|
self.write_allowed = defaultdict(list)
|
|
276 |
self._reset_allowed_paths()
|
276 |
277 |
|
277 |
278 |
self.lock_container_path = lock_container_path
|
278 |
279 |
self.wrapper.execute()
|
279 |
280 |
|
|
281 |
if account is None: # no path
|
|
282 |
return
|
|
283 |
|
|
284 |
# check permissions path
|
|
285 |
if action == 'read':
|
|
286 |
check_func = self.can_read
|
|
287 |
else:
|
|
288 |
check_func = self.can_write
|
|
289 |
check_func(user, account, container, name)
|
|
290 |
|
|
291 |
# lock container path if it is requested so
|
|
292 |
if container is not None and self.lock_container_path:
|
|
293 |
self._lookup_container(account, container)
|
|
294 |
|
280 |
295 |
def post_exec(self, success_status=True):
|
281 |
296 |
if success_status:
|
282 |
297 |
# send messages produced
|
... | ... | |
315 |
330 |
self.wrapper.close()
|
316 |
331 |
self.queue.close()
|
317 |
332 |
|
|
333 |
self.lock_container_path = None
|
|
334 |
self.container_tuple = None
|
|
335 |
|
|
336 |
self._reset_allowed_paths()
|
|
337 |
|
318 |
338 |
@property
|
319 |
339 |
def using_external_quotaholder(self):
|
320 |
340 |
return not isinstance(self.astakosclient, DisabledAstakosClient)
|
... | ... | |
496 |
516 |
raise NotAllowedError
|
497 |
517 |
allowed = self.permissions.access_list_paths(
|
498 |
518 |
user, '/'.join((account, container)))
|
499 |
|
path, node = self._lookup_container(account, container)
|
|
519 |
path, node = self._get_container_tuple(account, container)
|
500 |
520 |
before = until if until is not None else inf
|
501 |
521 |
allowed = self._get_formatted_paths(allowed)
|
502 |
522 |
return self.node.latest_attribute_keys(node, domain, before,
|
... | ... | |
511 |
531 |
if user != account:
|
512 |
532 |
if until:
|
513 |
533 |
raise NotAllowedError
|
514 |
|
path, node = self._lookup_container(account, container)
|
|
534 |
path, node = self._get_container_tuple(account, container)
|
515 |
535 |
props = self._get_properties(node, until)
|
516 |
536 |
mtime = props[self.MTIME]
|
517 |
537 |
count, bytes, tstamp = self._get_statistics(node, until)
|
... | ... | |
542 |
562 |
"""Update the metadata associated with the container for the domain."""
|
543 |
563 |
|
544 |
564 |
self.can_write(user, account, container)
|
545 |
|
path, node = self._lookup_container(account, container)
|
|
565 |
path, node = self._get_container_tuple(account, container)
|
546 |
566 |
src_version_id, dest_version_id = self._put_metadata(
|
547 |
567 |
user, node, domain, meta, replace,
|
548 |
568 |
update_statistics_ancestors_depth=0)
|
... | ... | |
560 |
580 |
self.can_read(user, account, container)
|
561 |
581 |
if user != account:
|
562 |
582 |
return {}
|
563 |
|
path, node = self._lookup_container(account, container)
|
|
583 |
path, node = self._get_container_tuple(account, container)
|
564 |
584 |
return self._get_policy(node, is_account_policy=False)
|
565 |
585 |
|
566 |
586 |
@debug_method
|
... | ... | |
569 |
589 |
"""Update the policy associated with the container."""
|
570 |
590 |
|
571 |
591 |
self.can_write(user, account, container)
|
572 |
|
path, node = self._lookup_container(account, container)
|
|
592 |
path, node = self._get_container_tuple(account, container)
|
573 |
593 |
self._check_policy(policy, is_account_policy=False)
|
574 |
594 |
self._put_policy(node, policy, replace, is_account_policy=False)
|
575 |
595 |
|
... | ... | |
580 |
600 |
self.can_write(user, account, container)
|
581 |
601 |
policy = policy or {}
|
582 |
602 |
try:
|
583 |
|
path, node = self._lookup_container(account, container)
|
|
603 |
path, node = self._get_container_tuple(account, container)
|
584 |
604 |
except NameError:
|
585 |
605 |
pass
|
586 |
606 |
else:
|
... | ... | |
599 |
619 |
"""Delete/purge the container with the given name."""
|
600 |
620 |
|
601 |
621 |
self.can_write(user, account, container)
|
602 |
|
path, node = self._lookup_container(account, container)
|
|
622 |
path, node = self._get_container_tuple(account, container)
|
603 |
623 |
|
604 |
624 |
if until is not None:
|
605 |
625 |
hashes, size, serials = self.node.node_purge_children(
|
... | ... | |
678 |
698 |
user, account, container, prefix, shared=True, public=False)
|
679 |
699 |
objects = set()
|
680 |
700 |
if shared_paths:
|
681 |
|
path, node = self._lookup_container(account, container)
|
|
701 |
path, node = self._get_container_tuple(account, container)
|
682 |
702 |
shared_paths = self._get_formatted_paths(shared_paths)
|
683 |
703 |
objects |= set(self._list_object_properties(
|
684 |
704 |
node, path, prefix, delimiter, marker, limit, virtual,
|
... | ... | |
704 |
724 |
user, account, container, prefix, shared, public)
|
705 |
725 |
if shared and not allowed:
|
706 |
726 |
return []
|
707 |
|
path, node = self._lookup_container(account, container)
|
|
727 |
path, node = self._get_container_tuple(account, container)
|
708 |
728 |
allowed = self._get_formatted_paths(allowed)
|
709 |
729 |
objects = self._list_object_properties(
|
710 |
730 |
node, path, prefix, delimiter, marker, limit, virtual, domain,
|
... | ... | |
907 |
927 |
self.permissions.access_set(path, permissions)
|
908 |
928 |
self._report_sharing_change(user, account, path, {'members':
|
909 |
929 |
self.permissions.access_members(path)})
|
|
930 |
# reset allowed paths since they may be affected
|
|
931 |
self._reset_allowed_paths()
|
910 |
932 |
|
911 |
933 |
@debug_method
|
912 |
934 |
def get_object_public(self, user, account, container, name):
|
... | ... | |
953 |
975 |
self._check_permissions(path, permissions)
|
954 |
976 |
|
955 |
977 |
account_path, account_node = self._lookup_account(account, True)
|
956 |
|
container_path, container_node = self._lookup_container(
|
|
978 |
container_path, container_node = self._get_container_tuple(
|
957 |
979 |
account, container)
|
958 |
980 |
|
959 |
981 |
path, node = self._put_object_node(
|
... | ... | |
1047 |
1069 |
self.can_write(user, account, container, name)
|
1048 |
1070 |
# Update objects with greater version and same hashmap
|
1049 |
1071 |
# and size (fix metadata updates).
|
1050 |
|
self._can_write(user, account, container, name)
|
|
1072 |
self.can_write(user, account, container, name)
|
1051 |
1073 |
path, node = self._lookup_object(account, container, name)
|
1052 |
1074 |
props = self._get_version(node, version)
|
1053 |
1075 |
versions = self.node.node_get_versions(node)
|
... | ... | |
1067 |
1089 |
report_size_change = not is_move
|
1068 |
1090 |
dest_meta = dest_meta or {}
|
1069 |
1091 |
dest_version_ids = []
|
1070 |
|
self._can_read(user, src_account, src_container, src_name)
|
1071 |
1092 |
path, node = self._lookup_object(src_account, src_container, src_name)
|
1072 |
1093 |
# TODO: Will do another fetch of the properties in duplicate version...
|
1073 |
1094 |
props = self._get_version(
|
... | ... | |
1129 |
1150 |
|
1130 |
1151 |
self.can_read(user, src_account, src_container, src_name)
|
1131 |
1152 |
self.can_write(user, dest_account, dest_container, dest_name)
|
|
1153 |
|
|
1154 |
# lock destination container
|
|
1155 |
self._lookup_container(dest_account, dest_container, lock=True)
|
1132 |
1156 |
meta = meta or {}
|
1133 |
1157 |
dest_version_id = self._copy_object(
|
1134 |
1158 |
user, src_account, src_container, src_name, dest_account,
|
... | ... | |
1145 |
1169 |
|
1146 |
1170 |
self.can_read(user, src_account, src_container, src_name)
|
1147 |
1171 |
self.can_write(user, dest_account, dest_container, dest_name)
|
|
1172 |
|
|
1173 |
# lock destination container path if it's not already locked
|
|
1174 |
if src_account != dest_account or src_container != dest_container:
|
|
1175 |
self._lookup_container(dest_account, dest_container, lock=True)
|
1148 |
1176 |
meta = meta or {}
|
1149 |
1177 |
if user != src_account:
|
1150 |
1178 |
raise NotAllowedError
|
... | ... | |
1269 |
1297 |
raise NameError
|
1270 |
1298 |
path, serial = info
|
1271 |
1299 |
account, container, name = path.split('/', 2)
|
1272 |
|
self._can_read(user, account, container, name)
|
|
1300 |
self.can_read(user, account, container, name)
|
1273 |
1301 |
return (account, container, name)
|
1274 |
1302 |
|
1275 |
1303 |
def get_block(self, hash):
|
... | ... | |
1325 |
1353 |
update_statistics_ancestors_depth=-1) # User is account.
|
1326 |
1354 |
return account, node
|
1327 |
1355 |
|
1328 |
|
def _lookup_container(self, account, container):
|
1329 |
|
for_update = True if self.lock_container_path else False
|
|
1356 |
def _lookup_container(self, account, container, lock=False):
|
|
1357 |
for_update = lock or self.lock_container_path
|
1330 |
1358 |
path = '/'.join((account, container))
|
1331 |
1359 |
node = self.node.node_lookup(path, for_update)
|
1332 |
1360 |
if node is None:
|
1333 |
1361 |
raise ItemNotExists('Container does not exist')
|
|
1362 |
self.container_path = path, node
|
1334 |
1363 |
return path, node
|
1335 |
1364 |
|
1336 |
1365 |
def _lookup_object(self, account, container, name):
|
... | ... | |
1587 |
1616 |
|
1588 |
1617 |
if version_id is None:
|
1589 |
1618 |
return 0
|
1590 |
|
path, node = self._lookup_container(account, container)
|
|
1619 |
path, node = self._get_container_tuple(account, container)
|
1591 |
1620 |
versioning = self._get_policy(
|
1592 |
1621 |
node, is_account_policy=False)['versioning']
|
1593 |
1622 |
if versioning != 'auto':
|
... | ... | |
1645 |
1674 |
return p
|
1646 |
1675 |
return None
|
1647 |
1676 |
|
|
1677 |
def _get_container_tuple(self, account, container):
|
|
1678 |
# Check if container_tuple is already set
|
|
1679 |
# and if it's not then call _lookup_container
|
|
1680 |
if self.container_tuple is not None:
|
|
1681 |
path, node = self.container_tuple
|
|
1682 |
if path == '/'.join((account, container)):
|
|
1683 |
return path, node
|
|
1684 |
return self._lookup_container(account, container)
|
|
1685 |
|
|
1686 |
def _reset_allowed_paths(self):
|
|
1687 |
self.read_allowed = defaultdict(list)
|
|
1688 |
self.write_allowed = defaultdict(list)
|
|
1689 |
|
1648 |
1690 |
def can_read(self, user, account, container=None, name=None):
|
1649 |
|
path = '/'.join((account, container or '', name or ''))
|
|
1691 |
path = '/'.join([p for p in (account, container, name) if
|
|
1692 |
p is not None])
|
1650 |
1693 |
if path in self.read_allowed[user]:
|
1651 |
1694 |
return
|
1652 |
1695 |
self._can_read(user, account, container, name)
|
1653 |
1696 |
self.read_allowed[user].append(path)
|
1654 |
1697 |
|
1655 |
1698 |
def can_write(self, user, account, container=None, name=None):
|
1656 |
|
path = '/'.join((account, container or '', name or ''))
|
|
1699 |
path = '/'.join([p for p in (account, container, name) if
|
|
1700 |
p is not None])
|
1657 |
1701 |
if path in self.write_allowed[user]:
|
1658 |
1702 |
return True
|
1659 |
1703 |
self._can_write(user, account, container, name)
|