Revision 469d0997
b/snf-astakos-app/astakos/im/cookie.py | ||
---|---|---|
40 | 40 |
from django.utils.translation import ugettext as _ |
41 | 41 |
|
42 | 42 |
from astakos.im.settings import ( |
43 |
COOKIE_NAME, COOKIE_DOMAIN, COOKIE_SECURE, LOGGING_LEVEL) |
|
43 |
COOKIE_NAME, COOKIE_DOMAIN, COOKIE_SECURE, LOGGING_LEVEL, TRANSLATE_UUIDS)
|
|
44 | 44 |
|
45 | 45 |
import astakos.im.messages as astakos_messages |
46 | 46 |
|
... | ... | |
69 | 69 |
|
70 | 70 |
@property |
71 | 71 |
def is_valid(self): |
72 |
return self.uuid == getattr(self.user, 'uuid', '') and \ |
|
73 |
self.auth_token == getattr(self.user, 'auth_token', '') |
|
72 |
cookie_attribute = 'uuid' if not TRANSLATE_UUIDS else 'username' |
|
73 |
return (self.uuid == getattr(self.user, cookie_attribute, '') and |
|
74 |
self.auth_token == getattr(self.user, 'auth_token', '')) |
|
74 | 75 |
|
75 | 76 |
@property |
76 | 77 |
def user(self): |
... | ... | |
81 | 82 |
raise ValueError(_(astakos_messages.NO_RESPONSE)) |
82 | 83 |
user = self.user |
83 | 84 |
expire_fmt = user.auth_token_expires.strftime('%a, %d-%b-%Y %H:%M:%S %Z') |
84 |
cookie_value = quote(user.uuid + '|' + user.auth_token) |
|
85 |
if TRANSLATE_UUIDS: |
|
86 |
cookie_value = quote(user.username + '|' + user.auth_token) |
|
87 |
else: |
|
88 |
cookie_value = quote(user.uuid + '|' + user.auth_token) |
|
85 | 89 |
self.response.set_cookie( |
86 | 90 |
COOKIE_NAME, value=cookie_value, expires=expire_fmt, path='/', |
87 | 91 |
domain=COOKIE_DOMAIN, secure=COOKIE_SECURE |
b/snf-astakos-app/astakos/im/settings.py | ||
---|---|---|
341 | 341 |
'ASTAKOS_ACTIVATION_REDIRECT_URL', |
342 | 342 |
"/im/landing") |
343 | 343 |
|
344 |
# If true, this enables a ui compatibility layer for the introduction of UUIDs |
|
345 |
# in identity management. WARNING: Setting to True will break your installation. |
|
346 |
TRANSLATE_UUIDS = getattr(settings, 'ASTAKOS_TRANSLATE_UUIDS', False) |
|
347 |
|
|
344 | 348 |
# Users that can approve or deny project applications from the web. |
345 | 349 |
PROJECT_ADMINS = getattr(settings, 'ASTAKOS_PROJECT_ADMINS', set()) |
b/snf-astakos-app/conf/20-snf-astakos-app-settings.conf | ||
---|---|---|
143 | 143 |
|
144 | 144 |
# UUIDs of users that can approve or deny project applications from the web. |
145 | 145 |
# ASTAKOS_PROJECT_ADMINS = set() # e.g. set(['01234567-89ab-cdef-0123-456789abcdef']) |
146 |
# |
|
147 |
# If true, this enables a ui compatibility layer for the introduction |
|
148 |
# of UUIDs in identity management. |
|
149 |
# WARNING: Setting to True will break your installation. |
|
150 |
# ASTAKOS_TRANSLATE_UUIDS = False |
b/snf-cyclades-app/synnefo/app_settings/default/plankton.py | ||
---|---|---|
18 | 18 |
|
19 | 19 |
# The owner of the images that will be marked as "system images" by the UI |
20 | 20 |
SYSTEM_IMAGES_OWNER = 'okeanos' |
21 |
|
|
22 |
# If true, this enables a ui compatibility layer for the introduction of UUIDs |
|
23 |
# in identity management. WARNING: Setting to True will break your installation. |
|
24 |
TRANSLATE_UUIDS = False |
b/snf-cyclades-app/synnefo/plankton/backend.py | ||
---|---|---|
55 | 55 |
|
56 | 56 |
from operator import itemgetter |
57 | 57 |
from time import gmtime, strftime |
58 |
from functools import wraps |
|
58 |
from functools import wraps, partial
|
|
59 | 59 |
|
60 | 60 |
from django.conf import settings |
61 | 61 |
|
62 | 62 |
from pithos.backends.base import NotAllowedError as PithosNotAllowedError |
63 |
import synnefo.lib.astakos as lib_astakos |
|
64 |
import logging |
|
65 |
|
|
66 |
logger = logging.getLogger(__name__) |
|
63 | 67 |
|
64 | 68 |
|
65 | 69 |
PLANKTON_DOMAIN = 'plankton' |
... | ... | |
69 | 73 |
PLANKTON_META = ('container_format', 'disk_format', 'name', 'properties', |
70 | 74 |
'status') |
71 | 75 |
|
76 |
TRANSLATE_UUIDS = getattr(settings, 'TRANSLATE_UUIDS', False) |
|
77 |
|
|
78 |
def get_displaynames(names): |
|
79 |
try: |
|
80 |
auth_url = settings.ASTAKOS_URL |
|
81 |
url = auth_url.replace('im/authenticate', 'service/api/user_catalogs') |
|
82 |
token = settings.CYCLADES_ASTAKOS_SERVICE_TOKEN |
|
83 |
uuids = lib_astakos.get_displaynames(token, names, url=url) |
|
84 |
except Exception, e: |
|
85 |
logger.exception(e) |
|
86 |
return {} |
|
87 |
|
|
88 |
return uuids |
|
89 |
|
|
72 | 90 |
|
73 | 91 |
def get_location(account, container, object): |
74 | 92 |
assert '/' not in account, "Invalid account" |
... | ... | |
158 | 176 |
image['id'] = meta['uuid'] |
159 | 177 |
image['is_public'] = '*' in permissions.get('read', []) |
160 | 178 |
image['location'] = location |
161 |
image['owner'] = account |
|
179 |
if TRANSLATE_UUIDS: |
|
180 |
displaynames = get_displaynames([account]) |
|
181 |
if account in displaynames: |
|
182 |
display_account = displaynames[account] |
|
183 |
else: |
|
184 |
display_account = 'unknown' |
|
185 |
image['owner'] = display_account |
|
186 |
else: |
|
187 |
image['owner'] = account |
|
162 | 188 |
image['size'] = meta['bytes'] |
163 | 189 |
image['store'] = 'pithos' |
164 | 190 |
image['updated_at'] = format_timestamp(meta['modified']) |
... | ... | |
305 | 331 |
# To get shared images, we connect as shared_from member and |
306 | 332 |
# get the list shared by us |
307 | 333 |
user = shared_from |
308 |
accounts = [self.user] |
|
309 | 334 |
else: |
310 | 335 |
user = None if public else self.user |
311 | 336 |
accounts = backend.list_accounts(user) |
b/snf-pithos-app/conf/20-snf-pithos-app-settings.conf | ||
---|---|---|
45 | 45 |
|
46 | 46 |
# Service Token acquired by identity provider. |
47 | 47 |
#PITHOS_SERVICE_TOKEN = '' |
48 |
|
|
49 |
# This enables a ui compatibility layer for the introduction of UUIDs in |
|
50 |
# identity management. WARNING: Setting to True will break your installation. |
|
51 |
# PITHOS_TRANSLATE_UUIDS = False |
b/snf-pithos-app/pithos/api/functions.py | ||
---|---|---|
42 | 42 |
from django.utils.encoding import smart_str |
43 | 43 |
from django.views.decorators.csrf import csrf_exempt |
44 | 44 |
|
45 |
from synnefo.lib.astakos import get_user |
|
45 |
from synnefo.lib.astakos import get_user, get_uuids as _get_uuids
|
|
46 | 46 |
|
47 | 47 |
from pithos.api.faults import ( |
48 | 48 |
Fault, NotModified, BadRequest, Unauthorized, Forbidden, ItemNotFound, |
... | ... | |
58 | 58 |
copy_or_move_object, get_int_parameter, get_content_length, |
59 | 59 |
get_content_range, socket_read_iterator, SaveToBackendHandler, |
60 | 60 |
object_data_response, put_object_block, hashmap_md5, simple_list_response, |
61 |
api_method, |
|
62 |
# retrieve_uuid
|
|
61 |
api_method, is_uuid,
|
|
62 |
retrieve_uuid, retrieve_displayname, retrieve_uuids, retrieve_displaynames
|
|
63 | 63 |
) |
64 | 64 |
|
65 |
from pithos.api.settings import UPDATE_MD5 |
|
65 |
from pithos.api.settings import (UPDATE_MD5, TRANSLATE_UUIDS, |
|
66 |
SERVICE_TOKEN, AUTHENTICATION_URL) |
|
66 | 67 |
|
67 | 68 |
from pithos.backends.base import ( |
68 | 69 |
NotAllowedError, QuotaError, ContainerNotEmpty, ItemNotExists, |
... | ... | |
73 | 74 |
import logging |
74 | 75 |
import hashlib |
75 | 76 |
|
76 |
|
|
77 | 77 |
logger = logging.getLogger(__name__) |
78 | 78 |
|
79 |
def get_uuids(names): |
|
80 |
try: |
|
81 |
uuids = _get_uuids(SERVICE_TOKEN, names, |
|
82 |
url=AUTHENTICATION_URL.replace( |
|
83 |
'im/authenticate', |
|
84 |
'service/api/user_catalogs')) |
|
85 |
except Exception, e: |
|
86 |
logger.exception(e) |
|
87 |
return {} |
|
88 |
|
|
89 |
return uuids |
|
90 |
|
|
79 | 91 |
|
80 | 92 |
@csrf_exempt |
81 | 93 |
def top_demux(request): |
... | ... | |
94 | 106 |
|
95 | 107 |
@csrf_exempt |
96 | 108 |
def account_demux(request, v_account): |
109 |
if TRANSLATE_UUIDS: |
|
110 |
if not is_uuid(v_account): |
|
111 |
uuids = get_uuids([v_account]) |
|
112 |
if not uuids or not v_account in uuids: |
|
113 |
return HttpResponse(status=404) |
|
114 |
v_account = uuids[v_account] |
|
115 |
|
|
97 | 116 |
if request.method == 'HEAD': |
98 | 117 |
return account_meta(request, v_account) |
99 | 118 |
elif request.method == 'POST': |
... | ... | |
106 | 125 |
|
107 | 126 |
@csrf_exempt |
108 | 127 |
def container_demux(request, v_account, v_container): |
128 |
if TRANSLATE_UUIDS: |
|
129 |
if not is_uuid(v_account): |
|
130 |
uuids = get_uuids([v_account]) |
|
131 |
if not uuids or not v_account in uuids: |
|
132 |
return HttpResponse(status=404) |
|
133 |
v_account = uuids[v_account] |
|
134 |
|
|
109 | 135 |
if request.method == 'HEAD': |
110 | 136 |
return container_meta(request, v_account, v_container) |
111 | 137 |
elif request.method == 'PUT': |
... | ... | |
123 | 149 |
@csrf_exempt |
124 | 150 |
def object_demux(request, v_account, v_container, v_object): |
125 | 151 |
# Helper to avoid placing the token in the URL when loading objects from a browser. |
152 |
if TRANSLATE_UUIDS: |
|
153 |
if not is_uuid(v_account): |
|
154 |
uuids = get_uuids([v_account]) |
|
155 |
if not uuids or not v_account in uuids: |
|
156 |
return HttpResponse(status=404) |
|
157 |
v_account = uuids[v_account] |
|
158 |
|
|
126 | 159 |
if request.method == 'HEAD': |
127 | 160 |
return object_meta(request, v_account, v_container, v_object) |
128 | 161 |
elif request.method == 'GET': |
... | ... | |
181 | 214 |
accounts = request.backend.list_accounts(request.user_uniq, marker, limit) |
182 | 215 |
|
183 | 216 |
if request.serialization == 'text': |
217 |
if TRANSLATE_UUIDS: |
|
218 |
accounts = retrieve_displaynames( |
|
219 |
getattr(request, 'token', None), accounts) |
|
184 | 220 |
if len(accounts) == 0: |
185 | 221 |
# The cloudfiles python bindings expect 200 if json/xml. |
186 | 222 |
response.status_code = 204 |
... | ... | |
208 | 244 |
meta['X-Account-Group'] = printable_header_dict( |
209 | 245 |
dict([(k, ','.join(v)) for k, v in groups.iteritems()])) |
210 | 246 |
account_meta.append(printable_header_dict(meta)) |
247 |
|
|
248 |
if TRANSLATE_UUIDS: |
|
249 |
uuids = list(d['name'] for d in account_meta) |
|
250 |
catalog = retrieve_displaynames( |
|
251 |
getattr(request, 'token', None), uuids, return_dict=True) |
|
252 |
for meta in account_meta: |
|
253 |
meta['name'] = catalog.get(meta.get('name')) |
|
254 |
|
|
211 | 255 |
if request.serialization == 'xml': |
212 | 256 |
data = render_to_string('accounts.xml', {'accounts': account_meta}) |
213 | 257 |
elif request.serialization == 'json': |
... | ... | |
231 | 275 |
external_quota=request.user_usage) |
232 | 276 |
groups = request.backend.get_account_groups( |
233 | 277 |
request.user_uniq, v_account) |
278 |
|
|
279 |
if TRANSLATE_UUIDS: |
|
280 |
for k in groups: |
|
281 |
groups[k] = retrieve_displaynames( |
|
282 |
getattr(request, 'token', None), groups[k]) |
|
234 | 283 |
policy = request.backend.get_account_policy( |
235 | 284 |
request.user_uniq, v_account, external_quota=request.user_usage) |
236 | 285 |
except NotAllowedError: |
... | ... | |
251 | 300 |
# badRequest (400) |
252 | 301 |
|
253 | 302 |
meta, groups = get_account_headers(request) |
254 |
# for k in groups: |
|
255 |
# try: |
|
256 |
# groups[k] = [retrieve_uuid(request.token, x) for x in groups[k]] |
|
257 |
# except ItemNotExists, e: |
|
258 |
# raise BadRequest( |
|
259 |
# 'Bad X-Account-Group header value: unknown account: %s' % e) |
|
303 |
for k in groups: |
|
304 |
if TRANSLATE_UUIDS: |
|
305 |
try: |
|
306 |
groups[k] = retrieve_uuids( |
|
307 |
getattr(request, 'token', None), |
|
308 |
groups[k], |
|
309 |
fail_silently=False) |
|
310 |
except ItemNotExists, e: |
|
311 |
raise BadRequest( |
|
312 |
'Bad X-Account-Group header value: %s' % e) |
|
313 |
else: |
|
314 |
try: |
|
315 |
retrieve_displaynames( |
|
316 |
getattr(request, 'token', None), |
|
317 |
groups[k], |
|
318 |
fail_silently=False) |
|
319 |
except ItemNotExists, e: |
|
320 |
raise BadRequest( |
|
321 |
'Bad X-Account-Group header value: %s' % e) |
|
260 | 322 |
replace = True |
261 | 323 |
if 'update' in request.GET: |
262 | 324 |
replace = False |
... | ... | |
636 | 698 |
|
637 | 699 |
object_meta = [] |
638 | 700 |
for meta in objects: |
701 |
if TRANSLATE_UUIDS: |
|
702 |
modified_by = meta.get('modified_by') |
|
703 |
if modified_by: |
|
704 |
l = retrieve_displaynames( |
|
705 |
getattr(request, 'token', None), [meta['modified_by']]) |
|
706 |
if l is not None and len(l) == 1: |
|
707 |
meta['modified_by'] = l[0] |
|
708 |
|
|
639 | 709 |
if len(meta) == 1: |
640 | 710 |
# Virtual objects/directories. |
641 | 711 |
object_meta.append(meta) |
... | ... | |
661 | 731 |
if public: |
662 | 732 |
update_public_meta(public, meta) |
663 | 733 |
object_meta.append(printable_header_dict(meta)) |
734 |
|
|
664 | 735 |
if request.serialization == 'xml': |
665 | 736 |
data = render_to_string( |
666 | 737 |
'objects.xml', {'container': v_container, 'objects': object_meta}) |
... | ... | |
715 | 786 |
return response |
716 | 787 |
|
717 | 788 |
response = HttpResponse(status=200) |
718 |
put_object_headers(response, meta) |
|
789 |
put_object_headers(response, meta, token=getattr(request, 'token', None))
|
|
719 | 790 |
return response |
720 | 791 |
|
721 | 792 |
|
... | ... | |
851 | 922 |
data = json.dumps(d) |
852 | 923 |
|
853 | 924 |
response = HttpResponse(data, status=200) |
854 |
put_object_headers(response, meta) |
|
925 |
put_object_headers( |
|
926 |
response, meta, token=getattr(request, 'token', None)) |
|
855 | 927 |
response['Content-Length'] = len(data) |
856 | 928 |
return response |
857 | 929 |
|
b/snf-pithos-app/pithos/api/settings.py | ||
---|---|---|
28 | 28 |
'http://localhost:8000/im/authenticate/') |
29 | 29 |
AUTHENTICATION_USERS = getattr(settings, 'PITHOS_AUTHENTICATION_USERS', {}) |
30 | 30 |
|
31 |
TRANSLATE_UUIDS = getattr(settings, 'PITHOS_TRANSLATE_UUIDS', False) |
|
32 |
|
|
31 | 33 |
COOKIE_NAME = getattr(settings, 'ASTAKOS_COOKIE_NAME', '_pithos2_a') |
32 | 34 |
|
33 | 35 |
# SQLAlchemy (choose SQLite/MySQL/PostgreSQL). |
b/snf-pithos-app/pithos/api/util.py | ||
---|---|---|
67 | 67 |
AUTHENTICATION_URL, AUTHENTICATION_USERS, |
68 | 68 |
COOKIE_NAME, USER_CATALOG_URL, |
69 | 69 |
RADOS_STORAGE, RADOS_POOL_BLOCKS, |
70 |
RADOS_POOL_MAPS) |
|
70 |
RADOS_POOL_MAPS, TRANSLATE_UUIDS)
|
|
71 | 71 |
from pithos.backends import connect_backend |
72 | 72 |
from pithos.backends.base import (NotAllowedError, QuotaError, ItemNotExists, |
73 | 73 |
VersionNotExists) |
... | ... | |
80 | 80 |
import uuid |
81 | 81 |
import decimal |
82 | 82 |
|
83 |
|
|
84 | 83 |
logger = logging.getLogger(__name__) |
85 | 84 |
|
86 | 85 |
|
... | ... | |
226 | 225 |
return content_type, meta, get_sharing(request), get_public(request) |
227 | 226 |
|
228 | 227 |
|
229 |
def put_object_headers(response, meta, restricted=False): |
|
228 |
def put_object_headers(response, meta, restricted=False, token=None):
|
|
230 | 229 |
response['ETag'] = meta['checksum'] |
231 | 230 |
response['Content-Length'] = meta['bytes'] |
232 | 231 |
response['Content-Type'] = meta.get('type', 'application/octet-stream') |
... | ... | |
234 | 233 |
if not restricted: |
235 | 234 |
response['X-Object-Hash'] = meta['hash'] |
236 | 235 |
response['X-Object-UUID'] = meta['uuid'] |
237 |
response['X-Object-Modified-By'] = smart_str( |
|
238 |
meta['modified_by'], strings_only=True) |
|
236 |
modified_by = retrieve_displayname(token, meta['modified_by']) |
|
237 |
if TRANSLATE_UUIDS: |
|
238 |
response['X-Object-Modified-By'] = smart_str( |
|
239 |
modified_by, strings_only=True) |
|
239 | 240 |
response['X-Object-Version'] = meta['version'] |
240 | 241 |
response['X-Object-Version-Timestamp'] = http_date( |
241 | 242 |
int(meta['version_timestamp'])) |
... | ... | |
291 | 292 |
# USER CATALOG utilities # |
292 | 293 |
########################## |
293 | 294 |
|
294 |
def retrieve_displayname(token, uuid): |
|
295 |
try: |
|
296 |
return get_displayname( |
|
295 |
def retrieve_displayname(token, uuid, fail_silently=True): |
|
296 |
displayname = get_displayname( |
|
297 | 297 |
token, uuid, USER_CATALOG_URL, AUTHENTICATION_USERS) |
298 |
except: |
|
299 |
# if it fails just leave the input intact |
|
298 |
if not displayname and not fail_silently: |
|
299 |
raise ItemNotExists(uuid) |
|
300 |
elif not displayname: |
|
301 |
# just return the uuid |
|
300 | 302 |
return uuid |
303 |
return displayname |
|
301 | 304 |
|
302 |
def retrieve_displaynames(token, uuids): |
|
303 |
return get_displaynames( |
|
304 |
token, uuids, USER_CATALOG_URL, AUTHENTICATION_USERS) |
|
305 |
def retrieve_displaynames(token, uuids, return_dict=False, fail_silently=True): |
|
306 |
catalog = get_displaynames( |
|
307 |
token, uuids, USER_CATALOG_URL, AUTHENTICATION_USERS) or {} |
|
308 |
missing = list(set(uuids) - set(catalog)) |
|
309 |
if missing and not fail_silently: |
|
310 |
raise ItemNotExists('Unknown displaynames: %s' % ', '.join(missing)) |
|
311 |
return catalog if return_dict else [catalog.get(i) for i in uuids] |
|
305 | 312 |
|
306 | 313 |
def retrieve_uuid(token, displayname): |
307 | 314 |
if is_uuid(displayname): |
... | ... | |
313 | 320 |
raise ItemNotExists(displayname) |
314 | 321 |
return uuid |
315 | 322 |
|
316 |
def retrieve_uuids(token, displaynames): |
|
317 |
return get_uuids( |
|
318 |
token, displaynames, USER_CATALOG_URL, AUTHENTICATION_USERS) |
|
323 |
def retrieve_uuids(token, displaynames, return_dict=False, fail_silently=True): |
|
324 |
catalog = get_uuids( |
|
325 |
token, displaynames, USER_CATALOG_URL, AUTHENTICATION_USERS) or {} |
|
326 |
missing = list(set(displaynames) - set(catalog)) |
|
327 |
if missing and not fail_silently: |
|
328 |
raise ItemNotExists('Unknown uuids: %s' % ', '.join(missing)) |
|
329 |
return catalog if return_dict else [catalog.get(i) for i in displaynames] |
|
319 | 330 |
|
320 | 331 |
def replace_permissions_displayname(token, holder): |
332 |
if holder == '*': |
|
333 |
return holder |
|
321 | 334 |
try: |
322 | 335 |
# check first for a group permission |
323 | 336 |
account, group = holder.split(':') |
324 | 337 |
except ValueError: |
325 |
return retrieve_uuid(holder) |
|
338 |
return retrieve_uuid(token, holder)
|
|
326 | 339 |
else: |
327 |
return ':'.join([retrieve_uuid(account), group]) |
|
340 |
return ':'.join([retrieve_uuid(token, account), group])
|
|
328 | 341 |
|
329 | 342 |
def replace_permissions_uuid(token, holder): |
343 |
if holder == '*': |
|
344 |
return holder |
|
330 | 345 |
try: |
331 | 346 |
# check first for a group permission |
332 | 347 |
account, group = holder.split(':') |
333 | 348 |
except ValueError: |
334 |
return retrieve_displayname(holder) |
|
349 |
return retrieve_displayname(token, holder)
|
|
335 | 350 |
else: |
336 |
return ':'.join([retrieve_displayname(account), group]) |
|
351 |
return ':'.join([retrieve_displayname(token, account), group])
|
|
337 | 352 |
|
338 | 353 |
def update_sharing_meta(request, permissions, v_account, v_container, v_object, meta): |
339 | 354 |
if permissions is None: |
... | ... | |
343 | 358 |
return |
344 | 359 |
|
345 | 360 |
# replace uuid with displayname |
346 |
# perms['read'] = [replace_permissions_uuid(request.token, x) for x in perms.get('read', [])] |
|
347 |
# perms['write'] = \ |
|
348 |
# [replace_permissions_uuid(request.token, x) for x in perms.get('write', [])] |
|
361 |
if TRANSLATE_UUIDS: |
|
362 |
perms['read'] = [replace_permissions_uuid( |
|
363 |
getattr(request, 'token', None), x) \ |
|
364 |
for x in perms.get('read', [])] |
|
365 |
perms['write'] = [replace_permissions_uuid( |
|
366 |
getattr(request, 'token', None), x) \ |
|
367 |
for x in perms.get('write', [])] |
|
349 | 368 |
|
350 | 369 |
ret = [] |
351 | 370 |
|
... | ... | |
598 | 617 |
'Bad X-Object-Sharing header value: missing prefix') |
599 | 618 |
|
600 | 619 |
# replace displayname with uuid |
601 |
# try: |
|
602 |
# ret['read'] = \ |
|
603 |
# [replace_permissions_displayname(request.token, x) for x in ret.get('read', [])] |
|
604 |
# ret['write'] = \ |
|
605 |
# [replace_permissions_displayname(request.token, x) for x in ret.get('write', [])] |
|
606 |
# except ItemNotExists, e: |
|
607 |
# raise BadRequest( |
|
608 |
# 'Bad X-Object-Sharing header value: unknown account: %s' % e) |
|
620 |
if TRANSLATE_UUIDS: |
|
621 |
try: |
|
622 |
ret['read'] = [replace_permissions_displayname( |
|
623 |
getattr(request, 'token', None), x) \ |
|
624 |
for x in ret.get('read', [])] |
|
625 |
ret['write'] = [replace_permissions_displayname( |
|
626 |
getattr(request, 'token', None), x) \ |
|
627 |
for x in ret.get('write', [])] |
|
628 |
except ItemNotExists, e: |
|
629 |
raise BadRequest( |
|
630 |
'Bad X-Object-Sharing header value: unknown account: %s' % e) |
|
609 | 631 |
|
610 | 632 |
# Keep duplicates only in write list. |
611 | 633 |
dups = [x for x in ret.get( |
... | ... | |
879 | 901 |
boundary = '' |
880 | 902 |
wrapper = ObjectWrapper(request.backend, ranges, sizes, hashmaps, boundary) |
881 | 903 |
response = HttpResponse(wrapper, status=ret) |
882 |
put_object_headers(response, meta, public) |
|
904 |
put_object_headers( |
|
905 |
response, meta, restricted=public, token=getattr(request, 'token', None)) |
|
883 | 906 |
if ret == 206: |
884 | 907 |
if len(ranges) == 1: |
885 | 908 |
offset, length = ranges[0] |
Also available in: Unified diff