Revision 297513ba
b/docs/source/devguide.rst | ||
---|---|---|
25 | 25 |
========================= ================================ |
26 | 26 |
Revision Description |
27 | 27 |
========================= ================================ |
28 |
0.7 (Oct 17, 2011) Suggest upload/download methods using hashmaps.
|
|
28 |
0.7 (Oct 21, 2011) Suggest upload/download methods using hashmaps.
|
|
29 | 29 |
\ Propose syncing algorithm. |
30 | 30 |
\ Support cross-account object copy and move. |
31 | 31 |
\ Pass token as a request parameter when using ``POST`` via an HTML form. |
... | ... | |
108 | 108 |
Return Code Description |
109 | 109 |
========================= ================================ |
110 | 110 |
400 (Bad Request) The request is invalid |
111 |
401 (Unauthorized) Request not allowed |
|
111 |
401 (Unauthorized) Missing or invalid token |
|
112 |
403 (Forbidden) Request not allowed |
|
112 | 113 |
404 (Not Found) The requested resource was not found |
113 | 114 |
503 (Service Unavailable) The request cannot be completed because of an internal error |
114 | 115 |
========================= ================================ |
b/pithos/api/functions.py | ||
---|---|---|
42 | 42 |
from django.utils.encoding import smart_unicode, smart_str |
43 | 43 |
from xml.dom import minidom |
44 | 44 |
|
45 |
from pithos.api.faults import (Fault, NotModified, BadRequest, Unauthorized, ItemNotFound, Conflict, |
|
45 |
from pithos.api.faults import (Fault, NotModified, BadRequest, Unauthorized, Forbidden, ItemNotFound, Conflict,
|
|
46 | 46 |
LengthRequired, PreconditionFailed, RequestEntityTooLarge, RangeNotSatisfiable, UnprocessableEntity) |
47 | 47 |
from pithos.api.util import (rename_meta_key, format_header_key, printable_header_dict, get_account_headers, |
48 | 48 |
put_account_headers, get_container_headers, put_container_headers, get_object_headers, put_object_headers, |
... | ... | |
113 | 113 |
def authenticate(request): |
114 | 114 |
# Normal Response Codes: 204 |
115 | 115 |
# Error Response Codes: serviceUnavailable (503), |
116 |
# unauthorized (401),
|
|
116 |
# forbidden (403),
|
|
117 | 117 |
# badRequest (400) |
118 | 118 |
|
119 | 119 |
x_auth_user = request.META.get('HTTP_X_AUTH_USER') |
... | ... | |
160 | 160 |
meta = request.backend.get_account_meta(request.user, x) |
161 | 161 |
groups = request.backend.get_account_groups(request.user, x) |
162 | 162 |
except NotAllowedError: |
163 |
raise Unauthorized('Access denied')
|
|
163 |
raise Forbidden('Not allowed')
|
|
164 | 164 |
else: |
165 | 165 |
rename_meta_key(meta, 'modified', 'last_modified') |
166 | 166 |
rename_meta_key(meta, 'until_timestamp', 'x_account_until_timestamp') |
... | ... | |
179 | 179 |
def account_meta(request, v_account): |
180 | 180 |
# Normal Response Codes: 204 |
181 | 181 |
# Error Response Codes: serviceUnavailable (503), |
182 |
# unauthorized (401),
|
|
182 |
# forbidden (403),
|
|
183 | 183 |
# badRequest (400) |
184 | 184 |
|
185 | 185 |
until = get_int_parameter(request.GET.get('until')) |
... | ... | |
188 | 188 |
groups = request.backend.get_account_groups(request.user, v_account) |
189 | 189 |
policy = request.backend.get_account_policy(request.user, v_account) |
190 | 190 |
except NotAllowedError: |
191 |
raise Unauthorized('Access denied')
|
|
191 |
raise Forbidden('Not allowed')
|
|
192 | 192 |
|
193 | 193 |
validate_modification_preconditions(request, meta) |
194 | 194 |
|
... | ... | |
200 | 200 |
def account_update(request, v_account): |
201 | 201 |
# Normal Response Codes: 202 |
202 | 202 |
# Error Response Codes: serviceUnavailable (503), |
203 |
# unauthorized (401),
|
|
203 |
# forbidden (403),
|
|
204 | 204 |
# badRequest (400) |
205 | 205 |
|
206 | 206 |
meta, groups = get_account_headers(request) |
... | ... | |
212 | 212 |
request.backend.update_account_groups(request.user, v_account, |
213 | 213 |
groups, replace) |
214 | 214 |
except NotAllowedError: |
215 |
raise Unauthorized('Access denied')
|
|
215 |
raise Forbidden('Not allowed')
|
|
216 | 216 |
except ValueError: |
217 | 217 |
raise BadRequest('Invalid groups header') |
218 | 218 |
if meta or replace: |
... | ... | |
220 | 220 |
request.backend.update_account_meta(request.user, v_account, meta, |
221 | 221 |
replace) |
222 | 222 |
except NotAllowedError: |
223 |
raise Unauthorized('Access denied')
|
|
223 |
raise Forbidden('Not allowed')
|
|
224 | 224 |
return HttpResponse(status=202) |
225 | 225 |
|
226 | 226 |
@api_method('GET', format_allowed=True) |
... | ... | |
228 | 228 |
# Normal Response Codes: 200, 204 |
229 | 229 |
# Error Response Codes: serviceUnavailable (503), |
230 | 230 |
# itemNotFound (404), |
231 |
# unauthorized (401),
|
|
231 |
# forbidden (403),
|
|
232 | 232 |
# badRequest (400) |
233 | 233 |
|
234 | 234 |
until = get_int_parameter(request.GET.get('until')) |
... | ... | |
237 | 237 |
groups = request.backend.get_account_groups(request.user, v_account) |
238 | 238 |
policy = request.backend.get_account_policy(request.user, v_account) |
239 | 239 |
except NotAllowedError: |
240 |
raise Unauthorized('Access denied')
|
|
240 |
raise Forbidden('Not allowed')
|
|
241 | 241 |
|
242 | 242 |
validate_modification_preconditions(request, meta) |
243 | 243 |
|
... | ... | |
257 | 257 |
containers = request.backend.list_containers(request.user, v_account, |
258 | 258 |
marker, limit, shared, until) |
259 | 259 |
except NotAllowedError: |
260 |
raise Unauthorized('Access denied')
|
|
260 |
raise Forbidden('Not allowed')
|
|
261 | 261 |
except NameError: |
262 | 262 |
containers = [] |
263 | 263 |
|
... | ... | |
278 | 278 |
policy = request.backend.get_container_policy(request.user, |
279 | 279 |
v_account, x) |
280 | 280 |
except NotAllowedError: |
281 |
raise Unauthorized('Access denied')
|
|
281 |
raise Forbidden('Not allowed')
|
|
282 | 282 |
except NameError: |
283 | 283 |
pass |
284 | 284 |
else: |
... | ... | |
300 | 300 |
# Normal Response Codes: 204 |
301 | 301 |
# Error Response Codes: serviceUnavailable (503), |
302 | 302 |
# itemNotFound (404), |
303 |
# unauthorized (401),
|
|
303 |
# forbidden (403),
|
|
304 | 304 |
# badRequest (400) |
305 | 305 |
|
306 | 306 |
until = get_int_parameter(request.GET.get('until')) |
... | ... | |
312 | 312 |
policy = request.backend.get_container_policy(request.user, v_account, |
313 | 313 |
v_container) |
314 | 314 |
except NotAllowedError: |
315 |
raise Unauthorized('Access denied')
|
|
315 |
raise Forbidden('Not allowed')
|
|
316 | 316 |
except NameError: |
317 | 317 |
raise ItemNotFound('Container does not exist') |
318 | 318 |
|
... | ... | |
327 | 327 |
# Normal Response Codes: 201, 202 |
328 | 328 |
# Error Response Codes: serviceUnavailable (503), |
329 | 329 |
# itemNotFound (404), |
330 |
# unauthorized (401),
|
|
330 |
# forbidden (403),
|
|
331 | 331 |
# badRequest (400) |
332 | 332 |
|
333 | 333 |
meta, policy = get_container_headers(request) |
... | ... | |
336 | 336 |
request.backend.put_container(request.user, v_account, v_container, policy) |
337 | 337 |
ret = 201 |
338 | 338 |
except NotAllowedError: |
339 |
raise Unauthorized('Access denied')
|
|
339 |
raise Forbidden('Not allowed')
|
|
340 | 340 |
except ValueError: |
341 | 341 |
raise BadRequest('Invalid policy header') |
342 | 342 |
except NameError: |
... | ... | |
347 | 347 |
request.backend.update_container_policy(request.user, v_account, |
348 | 348 |
v_container, policy, replace=False) |
349 | 349 |
except NotAllowedError: |
350 |
raise Unauthorized('Access denied')
|
|
350 |
raise Forbidden('Not allowed')
|
|
351 | 351 |
except NameError: |
352 | 352 |
raise ItemNotFound('Container does not exist') |
353 | 353 |
except ValueError: |
... | ... | |
357 | 357 |
request.backend.update_container_meta(request.user, v_account, |
358 | 358 |
v_container, meta, replace=False) |
359 | 359 |
except NotAllowedError: |
360 |
raise Unauthorized('Access denied')
|
|
360 |
raise Forbidden('Not allowed')
|
|
361 | 361 |
except NameError: |
362 | 362 |
raise ItemNotFound('Container does not exist') |
363 | 363 |
|
... | ... | |
368 | 368 |
# Normal Response Codes: 202 |
369 | 369 |
# Error Response Codes: serviceUnavailable (503), |
370 | 370 |
# itemNotFound (404), |
371 |
# unauthorized (401),
|
|
371 |
# forbidden (403),
|
|
372 | 372 |
# badRequest (400) |
373 | 373 |
|
374 | 374 |
meta, policy = get_container_headers(request) |
... | ... | |
380 | 380 |
request.backend.update_container_policy(request.user, v_account, |
381 | 381 |
v_container, policy, replace) |
382 | 382 |
except NotAllowedError: |
383 |
raise Unauthorized('Access denied')
|
|
383 |
raise Forbidden('Not allowed')
|
|
384 | 384 |
except NameError: |
385 | 385 |
raise ItemNotFound('Container does not exist') |
386 | 386 |
except ValueError: |
... | ... | |
390 | 390 |
request.backend.update_container_meta(request.user, v_account, |
391 | 391 |
v_container, meta, replace) |
392 | 392 |
except NotAllowedError: |
393 |
raise Unauthorized('Access denied')
|
|
393 |
raise Forbidden('Not allowed')
|
|
394 | 394 |
except NameError: |
395 | 395 |
raise ItemNotFound('Container does not exist') |
396 | 396 |
|
... | ... | |
417 | 417 |
# Error Response Codes: serviceUnavailable (503), |
418 | 418 |
# conflict (409), |
419 | 419 |
# itemNotFound (404), |
420 |
# unauthorized (401),
|
|
420 |
# forbidden (403),
|
|
421 | 421 |
# badRequest (400) |
422 | 422 |
|
423 | 423 |
until = get_int_parameter(request.GET.get('until')) |
... | ... | |
425 | 425 |
request.backend.delete_container(request.user, v_account, v_container, |
426 | 426 |
until) |
427 | 427 |
except NotAllowedError: |
428 |
raise Unauthorized('Access denied')
|
|
428 |
raise Forbidden('Not allowed')
|
|
429 | 429 |
except NameError: |
430 | 430 |
raise ItemNotFound('Container does not exist') |
431 | 431 |
except IndexError: |
... | ... | |
437 | 437 |
# Normal Response Codes: 200, 204 |
438 | 438 |
# Error Response Codes: serviceUnavailable (503), |
439 | 439 |
# itemNotFound (404), |
440 |
# unauthorized (401),
|
|
440 |
# forbidden (403),
|
|
441 | 441 |
# badRequest (400) |
442 | 442 |
|
443 | 443 |
until = get_int_parameter(request.GET.get('until')) |
... | ... | |
449 | 449 |
policy = request.backend.get_container_policy(request.user, v_account, |
450 | 450 |
v_container) |
451 | 451 |
except NotAllowedError: |
452 |
raise Unauthorized('Access denied')
|
|
452 |
raise Forbidden('Not allowed')
|
|
453 | 453 |
except NameError: |
454 | 454 |
raise ItemNotFound('Container does not exist') |
455 | 455 |
|
... | ... | |
498 | 498 |
v_container, prefix, delimiter, marker, |
499 | 499 |
limit, virtual, keys, shared, until) |
500 | 500 |
except NotAllowedError: |
501 |
raise Unauthorized('Access denied')
|
|
501 |
raise Forbidden('Not allowed')
|
|
502 | 502 |
except NameError: |
503 | 503 |
raise ItemNotFound('Container does not exist') |
504 | 504 |
|
... | ... | |
529 | 529 |
permissions = None |
530 | 530 |
public = None |
531 | 531 |
except NotAllowedError: |
532 |
raise Unauthorized('Access denied')
|
|
532 |
raise Forbidden('Not allowed')
|
|
533 | 533 |
except NameError: |
534 | 534 |
pass |
535 | 535 |
else: |
... | ... | |
553 | 553 |
# Normal Response Codes: 204 |
554 | 554 |
# Error Response Codes: serviceUnavailable (503), |
555 | 555 |
# itemNotFound (404), |
556 |
# unauthorized (401),
|
|
556 |
# forbidden (403),
|
|
557 | 557 |
# badRequest (400) |
558 | 558 |
|
559 | 559 |
version = request.GET.get('version') |
... | ... | |
569 | 569 |
permissions = None |
570 | 570 |
public = None |
571 | 571 |
except NotAllowedError: |
572 |
raise Unauthorized('Access denied')
|
|
572 |
raise Forbidden('Not allowed')
|
|
573 | 573 |
except NameError: |
574 | 574 |
raise ItemNotFound('Object does not exist') |
575 | 575 |
except IndexError: |
... | ... | |
599 | 599 |
# rangeNotSatisfiable (416), |
600 | 600 |
# preconditionFailed (412), |
601 | 601 |
# itemNotFound (404), |
602 |
# unauthorized (401),
|
|
602 |
# forbidden (403),
|
|
603 | 603 |
# badRequest (400), |
604 | 604 |
# notModified (304) |
605 | 605 |
|
... | ... | |
614 | 614 |
v = request.backend.list_versions(request.user, v_account, |
615 | 615 |
v_container, v_object) |
616 | 616 |
except NotAllowedError: |
617 |
raise Unauthorized('Access denied')
|
|
617 |
raise Forbidden('Not allowed')
|
|
618 | 618 |
d = {'versions': v} |
619 | 619 |
if request.serialization == 'xml': |
620 | 620 |
d['object'] = v_object |
... | ... | |
638 | 638 |
permissions = None |
639 | 639 |
public = None |
640 | 640 |
except NotAllowedError: |
641 |
raise Unauthorized('Access denied')
|
|
641 |
raise Forbidden('Not allowed')
|
|
642 | 642 |
except NameError: |
643 | 643 |
raise ItemNotFound('Object does not exist') |
644 | 644 |
except IndexError: |
... | ... | |
665 | 665 |
objects = request.backend.list_objects(request.user, v_account, |
666 | 666 |
src_container, prefix=src_name, virtual=False) |
667 | 667 |
except NotAllowedError: |
668 |
raise Unauthorized('Access denied')
|
|
668 |
raise Forbidden('Not allowed')
|
|
669 | 669 |
except ValueError: |
670 | 670 |
raise BadRequest('Invalid X-Object-Manifest header') |
671 | 671 |
except NameError: |
... | ... | |
678 | 678 |
sizes.append(s) |
679 | 679 |
hashmaps.append(h) |
680 | 680 |
except NotAllowedError: |
681 |
raise Unauthorized('Access denied')
|
|
681 |
raise Forbidden('Not allowed')
|
|
682 | 682 |
except NameError: |
683 | 683 |
raise ItemNotFound('Object does not exist') |
684 | 684 |
except IndexError: |
... | ... | |
690 | 690 |
sizes.append(s) |
691 | 691 |
hashmaps.append(h) |
692 | 692 |
except NotAllowedError: |
693 |
raise Unauthorized('Access denied')
|
|
693 |
raise Forbidden('Not allowed')
|
|
694 | 694 |
except NameError: |
695 | 695 |
raise ItemNotFound('Object does not exist') |
696 | 696 |
except IndexError: |
... | ... | |
727 | 727 |
# lengthRequired (411), |
728 | 728 |
# conflict (409), |
729 | 729 |
# itemNotFound (404), |
730 |
# unauthorized (401),
|
|
730 |
# forbidden (403),
|
|
731 | 731 |
# badRequest (400) |
732 | 732 |
|
733 | 733 |
# Evaluate conditions. |
... | ... | |
736 | 736 |
meta = request.backend.get_object_meta(request.user, v_account, |
737 | 737 |
v_container, v_object) |
738 | 738 |
except NotAllowedError: |
739 |
raise Unauthorized('Access denied')
|
|
739 |
raise Forbidden('Not allowed')
|
|
740 | 740 |
except NameError: |
741 | 741 |
meta = {} |
742 | 742 |
validate_matching_preconditions(request, meta) |
... | ... | |
829 | 829 |
v_account, v_container, v_object, size, hashmap, meta, |
830 | 830 |
True, permissions) |
831 | 831 |
except NotAllowedError: |
832 |
raise Unauthorized('Access denied')
|
|
832 |
raise Forbidden('Not allowed')
|
|
833 | 833 |
except IndexError, e: |
834 | 834 |
raise Conflict('\n'.join(e.data) + '\n') |
835 | 835 |
except NameError: |
... | ... | |
845 | 845 |
request.backend.update_object_public(request.user, v_account, |
846 | 846 |
v_container, v_object, public) |
847 | 847 |
except NotAllowedError: |
848 |
raise Unauthorized('Access denied')
|
|
848 |
raise Forbidden('Not allowed')
|
|
849 | 849 |
except NameError: |
850 | 850 |
raise ItemNotFound('Object does not exist') |
851 | 851 |
|
... | ... | |
859 | 859 |
# Normal Response Codes: 201 |
860 | 860 |
# Error Response Codes: serviceUnavailable (503), |
861 | 861 |
# itemNotFound (404), |
862 |
# unauthorized (401),
|
|
862 |
# forbidden (403),
|
|
863 | 863 |
# badRequest (400) |
864 | 864 |
|
865 | 865 |
if not request.FILES.has_key('X-Object-Data'): |
... | ... | |
883 | 883 |
version_id = request.backend.update_object_hashmap(request.user, |
884 | 884 |
v_account, v_container, v_object, size, hashmap, meta, True) |
885 | 885 |
except NotAllowedError: |
886 |
raise Unauthorized('Access denied')
|
|
886 |
raise Forbidden('Not allowed')
|
|
887 | 887 |
except NameError: |
888 | 888 |
raise ItemNotFound('Container does not exist') |
889 | 889 |
except QuotaError: |
... | ... | |
899 | 899 |
# Normal Response Codes: 201 |
900 | 900 |
# Error Response Codes: serviceUnavailable (503), |
901 | 901 |
# itemNotFound (404), |
902 |
# unauthorized (401),
|
|
902 |
# forbidden (403),
|
|
903 | 903 |
# badRequest (400) |
904 | 904 |
|
905 | 905 |
dest_account = smart_unicode(request.META.get('HTTP_DESTINATION_ACCOUNT'), strings_only=True) |
... | ... | |
920 | 920 |
meta = request.backend.get_object_meta(request.user, v_account, |
921 | 921 |
v_container, v_object, src_version) |
922 | 922 |
except NotAllowedError: |
923 |
raise Unauthorized('Access denied')
|
|
923 |
raise Forbidden('Not allowed')
|
|
924 | 924 |
except (NameError, IndexError): |
925 | 925 |
raise ItemNotFound('Container or object does not exist') |
926 | 926 |
validate_matching_preconditions(request, meta) |
... | ... | |
936 | 936 |
# Normal Response Codes: 201 |
937 | 937 |
# Error Response Codes: serviceUnavailable (503), |
938 | 938 |
# itemNotFound (404), |
939 |
# unauthorized (401),
|
|
939 |
# forbidden (403),
|
|
940 | 940 |
# badRequest (400) |
941 | 941 |
|
942 | 942 |
dest_account = smart_unicode(request.META.get('HTTP_DESTINATION_ACCOUNT'), strings_only=True) |
... | ... | |
956 | 956 |
meta = request.backend.get_object_meta(request.user, v_account, |
957 | 957 |
v_container, v_object) |
958 | 958 |
except NotAllowedError: |
959 |
raise Unauthorized('Access denied')
|
|
959 |
raise Forbidden('Not allowed')
|
|
960 | 960 |
except NameError: |
961 | 961 |
raise ItemNotFound('Container or object does not exist') |
962 | 962 |
validate_matching_preconditions(request, meta) |
... | ... | |
973 | 973 |
# Error Response Codes: serviceUnavailable (503), |
974 | 974 |
# conflict (409), |
975 | 975 |
# itemNotFound (404), |
976 |
# unauthorized (401),
|
|
976 |
# forbidden (403),
|
|
977 | 977 |
# badRequest (400) |
978 | 978 |
meta, permissions, public = get_object_headers(request) |
979 | 979 |
content_type = meta.get('Content-Type') |
... | ... | |
984 | 984 |
prev_meta = request.backend.get_object_meta(request.user, v_account, |
985 | 985 |
v_container, v_object) |
986 | 986 |
except NotAllowedError: |
987 |
raise Unauthorized('Access denied')
|
|
987 |
raise Forbidden('Not allowed')
|
|
988 | 988 |
except NameError: |
989 | 989 |
raise ItemNotFound('Object does not exist') |
990 | 990 |
|
... | ... | |
1012 | 1012 |
request.backend.update_object_permissions(request.user, |
1013 | 1013 |
v_account, v_container, v_object, permissions) |
1014 | 1014 |
except NotAllowedError: |
1015 |
raise Unauthorized('Access denied')
|
|
1015 |
raise Forbidden('Not allowed')
|
|
1016 | 1016 |
except NameError: |
1017 | 1017 |
raise ItemNotFound('Object does not exist') |
1018 | 1018 |
except ValueError: |
... | ... | |
1024 | 1024 |
request.backend.update_object_public(request.user, v_account, |
1025 | 1025 |
v_container, v_object, public) |
1026 | 1026 |
except NotAllowedError: |
1027 |
raise Unauthorized('Access denied')
|
|
1027 |
raise Forbidden('Not allowed')
|
|
1028 | 1028 |
except NameError: |
1029 | 1029 |
raise ItemNotFound('Object does not exist') |
1030 | 1030 |
if meta or replace: |
... | ... | |
1032 | 1032 |
version_id = request.backend.update_object_meta(request.user, |
1033 | 1033 |
v_account, v_container, v_object, meta, replace) |
1034 | 1034 |
except NotAllowedError: |
1035 |
raise Unauthorized('Access denied')
|
|
1035 |
raise Forbidden('Not allowed')
|
|
1036 | 1036 |
except NameError: |
1037 | 1037 |
raise ItemNotFound('Object does not exist') |
1038 | 1038 |
response['X-Object-Version'] = version_id |
... | ... | |
1053 | 1053 |
size, hashmap = request.backend.get_object_hashmap(request.user, |
1054 | 1054 |
v_account, v_container, v_object) |
1055 | 1055 |
except NotAllowedError: |
1056 |
raise Unauthorized('Access denied')
|
|
1056 |
raise Forbidden('Not allowed')
|
|
1057 | 1057 |
except NameError: |
1058 | 1058 |
raise ItemNotFound('Object does not exist') |
1059 | 1059 |
|
... | ... | |
1074 | 1074 |
src_size, src_hashmap = request.backend.get_object_hashmap(request.user, |
1075 | 1075 |
src_account, src_container, src_name, src_version) |
1076 | 1076 |
except NotAllowedError: |
1077 |
raise Unauthorized('Access denied')
|
|
1077 |
raise Forbidden('Not allowed')
|
|
1078 | 1078 |
except NameError: |
1079 | 1079 |
raise ItemNotFound('Source object does not exist') |
1080 | 1080 |
|
... | ... | |
1160 | 1160 |
v_account, v_container, v_object, size, hashmap, meta, |
1161 | 1161 |
replace, permissions) |
1162 | 1162 |
except NotAllowedError: |
1163 |
raise Unauthorized('Access denied')
|
|
1163 |
raise Forbidden('Not allowed')
|
|
1164 | 1164 |
except NameError: |
1165 | 1165 |
raise ItemNotFound('Container does not exist') |
1166 | 1166 |
except ValueError: |
... | ... | |
1174 | 1174 |
request.backend.update_object_public(request.user, v_account, |
1175 | 1175 |
v_container, v_object, public) |
1176 | 1176 |
except NotAllowedError: |
1177 |
raise Unauthorized('Access denied')
|
|
1177 |
raise Forbidden('Not allowed')
|
|
1178 | 1178 |
except NameError: |
1179 | 1179 |
raise ItemNotFound('Object does not exist') |
1180 | 1180 |
|
... | ... | |
1188 | 1188 |
# Normal Response Codes: 204 |
1189 | 1189 |
# Error Response Codes: serviceUnavailable (503), |
1190 | 1190 |
# itemNotFound (404), |
1191 |
# unauthorized (401),
|
|
1191 |
# forbidden (403),
|
|
1192 | 1192 |
# badRequest (400) |
1193 | 1193 |
|
1194 | 1194 |
until = get_int_parameter(request.GET.get('until')) |
... | ... | |
1196 | 1196 |
request.backend.delete_object(request.user, v_account, v_container, |
1197 | 1197 |
v_object, until) |
1198 | 1198 |
except NotAllowedError: |
1199 |
raise Unauthorized('Access denied')
|
|
1199 |
raise Forbidden('Not allowed')
|
|
1200 | 1200 |
except NameError: |
1201 | 1201 |
raise ItemNotFound('Object does not exist') |
1202 | 1202 |
return HttpResponse(status=204) |
b/pithos/api/util.py | ||
---|---|---|
45 | 45 |
from django.utils.encoding import smart_str |
46 | 46 |
|
47 | 47 |
from pithos.api.compat import parse_http_date_safe, parse_http_date |
48 |
from pithos.api.faults import (Fault, NotModified, BadRequest, Unauthorized, ItemNotFound, |
|
48 |
from pithos.api.faults import (Fault, NotModified, BadRequest, Unauthorized, Forbidden, ItemNotFound,
|
|
49 | 49 |
Conflict, LengthRequired, PreconditionFailed, RequestEntityTooLarge, |
50 | 50 |
RangeNotSatisfiable, ServiceUnavailable) |
51 | 51 |
from pithos.backends import connect_backend |
... | ... | |
303 | 303 |
dest_account, dest_container, dest_name, |
304 | 304 |
meta, False, permissions, src_version) |
305 | 305 |
except NotAllowedError: |
306 |
raise Unauthorized('Access denied')
|
|
306 |
raise Forbidden('Not allowed')
|
|
307 | 307 |
except (NameError, IndexError): |
308 | 308 |
raise ItemNotFound('Container or object does not exist') |
309 | 309 |
except ValueError: |
... | ... | |
316 | 316 |
try: |
317 | 317 |
request.backend.update_object_public(request.user, dest_account, dest_container, dest_name, public) |
318 | 318 |
except NotAllowedError: |
319 |
raise Unauthorized('Access denied')
|
|
319 |
raise Forbidden('Not allowed')
|
|
320 | 320 |
except NameError: |
321 | 321 |
raise ItemNotFound('Object does not exist') |
322 | 322 |
return version_id |
... | ... | |
767 | 767 |
|
768 | 768 |
return 'text' |
769 | 769 |
|
770 |
def api_method(http_method=None, format_allowed=False): |
|
770 |
def api_method(http_method=None, format_allowed=False, user_required=True):
|
|
771 | 771 |
"""Decorator function for views that implement an API method.""" |
772 | 772 |
|
773 | 773 |
def decorator(func): |
... | ... | |
776 | 776 |
try: |
777 | 777 |
if http_method and request.method != http_method: |
778 | 778 |
raise BadRequest('Method not allowed.') |
779 |
if user_required and getattr(request, 'user', None) is None: |
|
780 |
raise Unauthorized('Access denied') |
|
779 | 781 |
|
780 | 782 |
# The args variable may contain up to (account, container, object). |
781 | 783 |
if len(args) > 1 and len(args[1]) > 256: |
... | ... | |
797 | 799 |
fault = ServiceUnavailable('Unexpected error') |
798 | 800 |
return render_fault(request, fault) |
799 | 801 |
finally: |
800 |
request.backend.wrapper.conn.close() |
|
802 |
if getattr(request, 'backend', None) is not None: |
|
803 |
request.backend.wrapper.conn.close() |
|
801 | 804 |
return wrapper |
802 | 805 |
return decorator |
b/pithos/public/functions.py | ||
---|---|---|
52 | 52 |
else: |
53 | 53 |
return method_not_allowed(request) |
54 | 54 |
|
55 |
# TODO: Use a version of api_method that does not check for a token. |
|
56 |
|
|
57 |
@api_method('HEAD') |
|
55 |
@api_method('HEAD', user_required=False) |
|
58 | 56 |
def object_meta(request, v_account, v_container, v_object): |
59 | 57 |
# Normal Response Codes: 204 |
60 | 58 |
# Error Response Codes: serviceUnavailable (503), |
61 | 59 |
# itemNotFound (404), |
62 |
# unauthorized (401), |
|
63 | 60 |
# badRequest (400) |
64 | 61 |
|
65 | 62 |
try: |
... | ... | |
78 | 75 |
put_object_meta(response, meta, True) |
79 | 76 |
return response |
80 | 77 |
|
81 |
@api_method('GET') |
|
78 |
@api_method('GET', user_required=False)
|
|
82 | 79 |
def object_read(request, v_account, v_container, v_object): |
83 | 80 |
# Normal Response Codes: 200, 206 |
84 | 81 |
# Error Response Codes: serviceUnavailable (503), |
85 | 82 |
# rangeNotSatisfiable (416), |
86 | 83 |
# preconditionFailed (412), |
87 | 84 |
# itemNotFound (404), |
88 |
# unauthorized (401), |
|
89 | 85 |
# badRequest (400), |
90 | 86 |
# notModified (304) |
91 | 87 |
|
... | ... | |
139 | 135 |
|
140 | 136 |
return object_data_response(request, sizes, hashmaps, meta, True) |
141 | 137 |
|
142 |
@api_method() |
|
138 |
@api_method(user_required=False)
|
|
143 | 139 |
def method_not_allowed(request, **v_args): |
144 | 140 |
raise ItemNotFound('Object does not exist') |
b/tools/test | ||
---|---|---|
125 | 125 |
'content_type', |
126 | 126 |
'content_encoding', |
127 | 127 |
'last_modified',)} |
128 |
self.return_codes = (400, 401, 404, 503,) |
|
128 |
self.return_codes = (400, 401, 403, 404, 503,)
|
|
129 | 129 |
|
130 | 130 |
def tearDown(self): |
131 | 131 |
self._clean_account() |
... | ... | |
333 | 333 |
size = size + int(m['x-container-bytes-used']) |
334 | 334 |
self.assertEqual(meta['x-account-bytes-used'], str(size)) |
335 | 335 |
|
336 |
def test_get_account_401(self):
|
|
337 |
self.assert_raises_fault(401,
|
|
336 |
def test_get_account_403(self):
|
|
337 |
self.assert_raises_fault(403,
|
|
338 | 338 |
self.invalid_client.retrieve_account_metadata) |
339 | 339 |
|
340 | 340 |
def test_get_account_meta_until(self): |
... | ... | |
371 | 371 |
containers = self.client.list_containers() |
372 | 372 |
self.assertEquals(self.containers, containers) |
373 | 373 |
|
374 |
def test_list_401(self):
|
|
375 |
self.assert_raises_fault(401, self.invalid_client.list_containers)
|
|
374 |
def test_list_403(self):
|
|
375 |
self.assert_raises_fault(403, self.invalid_client.list_containers)
|
|
376 | 376 |
|
377 | 377 |
def test_list_with_limit(self): |
378 | 378 |
limit = 2 |
... | ... | |
509 | 509 |
|
510 | 510 |
def test_invalid_account_update_meta(self): |
511 | 511 |
meta = {'test':'test', 'tost':'tost'} |
512 |
self.assert_raises_fault(401,
|
|
512 |
self.assert_raises_fault(403,
|
|
513 | 513 |
self.invalid_client.update_account_metadata, |
514 | 514 |
**meta) |
515 | 515 |
|
... | ... | |
1889 | 1889 |
'0009', |
1890 | 1890 |
'διογένης', |
1891 | 1891 |
get_api()) |
1892 |
self.assert_not_raises_fault(401, chef.retrieve_object_metadata,
|
|
1892 |
self.assert_not_raises_fault(403, chef.retrieve_object_metadata,
|
|
1893 | 1893 |
'φάκελος', 'ο1', account=get_user()) |
1894 | 1894 |
|
1895 | 1895 |
#check write access |
1896 | 1896 |
self.client.share_object('φάκελος', 'ο1', ['διογένης'], read=False) |
1897 | 1897 |
new_data = get_random_data() |
1898 |
self.assert_not_raises_fault(401, chef.update_object,
|
|
1898 |
self.assert_not_raises_fault(403, chef.update_object,
|
|
1899 | 1899 |
'φάκελος', 'ο1', StringIO(new_data), |
1900 | 1900 |
account=get_user()) |
1901 | 1901 |
|
... | ... | |
1969 | 1969 |
for token, account in OTHER_ACCOUNTS.items(): |
1970 | 1970 |
cl = Pithos_Client(get_server(), token, account, get_api()) |
1971 | 1971 |
if account in authorized or any: |
1972 |
self.assert_not_raises_fault(401, cl.retrieve_object_metadata,
|
|
1972 |
self.assert_not_raises_fault(403, cl.retrieve_object_metadata,
|
|
1973 | 1973 |
'c', 'o', account=get_user()) |
1974 | 1974 |
else: |
1975 |
self.assert_raises_fault(401, cl.retrieve_object_metadata,
|
|
1975 |
self.assert_raises_fault(403, cl.retrieve_object_metadata,
|
|
1976 | 1976 |
'c', 'o', account=get_user()) |
1977 | 1977 |
|
1978 | 1978 |
#check inheritance |
... | ... | |
1980 | 1980 |
for token, account in OTHER_ACCOUNTS.items(): |
1981 | 1981 |
cl = Pithos_Client(get_server(), token, account, get_api()) |
1982 | 1982 |
if account in authorized or any: |
1983 |
self.assert_not_raises_fault(401, cl.retrieve_object_metadata,
|
|
1983 |
self.assert_not_raises_fault(403, cl.retrieve_object_metadata,
|
|
1984 | 1984 |
'c', 'o/also-shared', account=get_user()) |
1985 | 1985 |
else: |
1986 |
self.assert_raises_fault(401, cl.retrieve_object_metadata,
|
|
1986 |
self.assert_raises_fault(403, cl.retrieve_object_metadata,
|
|
1987 | 1987 |
'c', 'o/also-shared', account=get_user()) |
1988 | 1988 |
|
1989 | 1989 |
def assert_write(self, o_data, authorized=[], any=False): |
... | ... | |
1992 | 1992 |
new_data = get_random_data() |
1993 | 1993 |
if account in authorized or any: |
1994 | 1994 |
# test write access |
1995 |
self.assert_not_raises_fault(401, cl.update_object,
|
|
1995 |
self.assert_not_raises_fault(403, cl.update_object,
|
|
1996 | 1996 |
'c', 'o', StringIO(new_data), |
1997 | 1997 |
account=get_user()) |
1998 | 1998 |
try: |
... | ... | |
2002 | 2002 |
self.assertEqual(new_data, server_data[len(o_data):]) |
2003 | 2003 |
o_data = server_data |
2004 | 2004 |
except Fault, f: |
2005 |
self.failIf(f.status == 401)
|
|
2005 |
self.failIf(f.status == 403)
|
|
2006 | 2006 |
else: |
2007 |
self.assert_raises_fault(401, cl.update_object,
|
|
2007 |
self.assert_raises_fault(403, cl.update_object,
|
|
2008 | 2008 |
'c', 'o', StringIO(new_data), |
2009 | 2009 |
account=get_user()) |
2010 | 2010 |
|
... | ... | |
2016 | 2016 |
new_data = get_random_data() |
2017 | 2017 |
if account in authorized or any: |
2018 | 2018 |
# test write access |
2019 |
self.assert_not_raises_fault(401, cl.update_object,
|
|
2019 |
self.assert_not_raises_fault(403, cl.update_object,
|
|
2020 | 2020 |
'c', o['name'], |
2021 | 2021 |
StringIO(new_data), |
2022 | 2022 |
account=get_user()) |
... | ... | |
2026 | 2026 |
self.assertEqual(new_data, server_data[len(o_data):]) |
2027 | 2027 |
o_data = server_data |
2028 | 2028 |
except Fault, f: |
2029 |
self.failIf(f.status == 401)
|
|
2029 |
self.failIf(f.status == 403)
|
|
2030 | 2030 |
else: |
2031 |
self.assert_raises_fault(401, cl.update_object,
|
|
2031 |
self.assert_raises_fault(403, cl.update_object,
|
|
2032 | 2032 |
'c', o['name'], |
2033 | 2033 |
StringIO(new_data), |
2034 | 2034 |
account=get_user()) |
Also available in: Unified diff