Replace uniq with userid.
[pithos] / snf-pithos-app / pithos / api / public.py
1 # Copyright 2011-2012 GRNET S.A. All rights reserved.
2
3 # Redistribution and use in source and binary forms, with or
4 # without modification, are permitted provided that the following
5 # conditions are met:
6
7 #   1. Redistributions of source code must retain the above
8 #      copyright notice, this list of conditions and the following
9 #      disclaimer.
10
11 #   2. Redistributions in binary form must reproduce the above
12 #      copyright notice, this list of conditions and the following
13 #      disclaimer in the documentation and/or other materials
14 #      provided with the distribution.
15
16 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
28
29 # The views and conclusions contained in the software and
30 # documentation are those of the authors and should not be
31 # interpreted as representing official policies, either expressed
32 # or implied, of GRNET S.A.
33
34 import logging
35
36 from django.http import HttpResponse
37 from django.views.decorators.csrf import csrf_exempt
38
39 from synnefo.lib.astakos import get_user
40
41 from pithos.api.faults import (Fault, BadRequest, ItemNotFound)
42 from pithos.api.util import (put_object_headers, update_manifest_meta,
43     validate_modification_preconditions, validate_matching_preconditions,
44     object_data_response, api_method)
45 from pithos.api.short_url import decode_url
46 from pithos.api.settings import AUTHENTICATION_URL, AUTHENTICATION_USERS
47
48
49 logger = logging.getLogger(__name__)
50
51
52 @csrf_exempt
53 def public_demux(request, v_public):
54     get_user(request, AUTHENTICATION_URL, AUTHENTICATION_USERS)
55     if request.method == 'HEAD':
56         return public_meta(request, v_public)
57     elif request.method == 'GET':
58         return public_read(request, v_public)
59     else:
60         return method_not_allowed(request)
61
62 @api_method('HEAD', user_required=False)
63 def public_meta(request, v_public):
64     # Normal Response Codes: 204
65     # Error Response Codes: internalServerError (500),
66     #                       itemNotFound (404),
67     #                       badRequest (400)
68     
69     try:
70         v_account, v_container, v_object = request.backend.get_public(request.userid,
71                                                     decode_url(v_public))
72         meta = request.backend.get_object_meta(request.userid, v_account,
73                                                     v_container, v_object, 'pithos')
74         public = request.backend.get_object_public(request.userid, v_account,
75                                                     v_container, v_object)
76     except:
77         raise ItemNotFound('Object does not exist')
78     
79     if not public:
80         raise ItemNotFound('Object does not exist')
81     update_manifest_meta(request, v_account, meta)
82     
83     response = HttpResponse(status=200)
84     put_object_headers(response, meta, True)
85     return response
86
87 @api_method('GET', user_required=False)
88 def public_read(request, v_public):
89     # Normal Response Codes: 200, 206
90     # Error Response Codes: internalServerError (500),
91     #                       rangeNotSatisfiable (416),
92     #                       preconditionFailed (412),
93     #                       itemNotFound (404),
94     #                       badRequest (400),
95     #                       notModified (304)
96     
97     try:
98         v_account, v_container, v_object = request.backend.get_public(request.userid,
99                                                     decode_url(v_public))
100         meta = request.backend.get_object_meta(request.userid, v_account,
101                                                     v_container, v_object, 'pithos')
102         public = request.backend.get_object_public(request.userid, v_account,
103                                                     v_container, v_object)
104     except:
105         raise ItemNotFound('Object does not exist')
106     
107     if not public:
108         raise ItemNotFound('Object does not exist')
109     update_manifest_meta(request, v_account, meta)
110     
111     # Evaluate conditions.
112     validate_modification_preconditions(request, meta)
113     try:
114         validate_matching_preconditions(request, meta)
115     except NotModified:
116         response = HttpResponse(status=304)
117         response['ETag'] = meta['ETag']
118         return response
119     
120     sizes = []
121     hashmaps = []
122     if 'X-Object-Manifest' in meta:
123         try:
124             src_container, src_name = split_container_object_string('/' + meta['X-Object-Manifest'])
125             objects = request.backend.list_objects(request.userid, v_account,
126                                 src_container, prefix=src_name, virtual=False)
127         except:
128             raise ItemNotFound('Object does not exist')
129         
130         try:
131             for x in objects:
132                 s, h = request.backend.get_object_hashmap(request.userid,
133                                         v_account, src_container, x[0], x[1])
134                 sizes.append(s)
135                 hashmaps.append(h)
136         except:
137             raise ItemNotFound('Object does not exist')
138     else:
139         try:
140             s, h = request.backend.get_object_hashmap(request.userid, v_account,
141                                                         v_container, v_object)
142             sizes.append(s)
143             hashmaps.append(h)
144         except:
145             raise ItemNotFound('Object does not exist')
146     
147     if 'Content-Disposition' not in meta:
148         name = v_object.rstrip('/').split('/')[-1]
149         if not name:
150             name = v_public
151         meta['Content-Disposition'] = 'attachment; filename=%s' % (name,)
152     
153     return object_data_response(request, sizes, hashmaps, meta, True)
154
155 @api_method(user_required=False)
156 def method_not_allowed(request, **v_args):
157     raise ItemNotFound('Object does not exist')