Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-app / pithos / api / test / public.py @ 7e402b46

History | View | Annotate | Download (9.2 kB)

1
# Copyright 2011 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 random
35
import datetime
36
import time as _time
37

    
38
from synnefo.lib import join_urls
39

    
40
import django.utils.simplejson as json
41

    
42
from pithos.api.test import PithosAPITest
43
from pithos.api.test.util import get_random_name
44
from pithos.api import settings as pithos_settings
45

    
46

    
47
class TestPublic(PithosAPITest):
48
    def _assert_not_public_object(self, cname, oname):
49
        info = self.get_object_info(cname, oname)
50
        self.assertTrue('X-Object-Public' not in info)
51

    
52
    def _assert_public_object(self, cname, oname, odata):
53
        info = self.get_object_info(cname, oname)
54
        self.assertTrue('X-Object-Public' in info)
55
        public = info['X-Object-Public']
56

    
57
        self.assertTrue(len(public) >= pithos_settings.PUBLIC_URL_SECURITY)
58
        (self.assertTrue(l in pithos_settings.PUBLIC_URL_ALPHABET) for
59
         l in public)
60

    
61
        r = self.get(public, user='user2', token=None)
62
        self.assertEqual(r.status_code, 200)
63
        self.assertTrue('X-Object-Public' not in r)
64

    
65
        self.assertEqual(r.content, odata)
66

    
67
        # assert other users cannot access the object using the priavate path
68
        url = join_urls(self.pithos_path, self.user, cname, oname)
69
        r = self.head(url, user='user2')
70
        self.assertEqual(r.status_code, 403)
71

    
72
        r = self.get(url, user='user2')
73
        self.assertEqual(r.status_code, 403)
74

    
75
        return public
76

    
77
    def test_set_object_public(self):
78
        cname = get_random_name()
79
        self.create_container(cname)
80
        oname, odata = self.upload_object(cname)[:-1]
81
        self._assert_not_public_object(cname, oname)
82

    
83
        # set public
84
        url = join_urls(self.pithos_path, self.user, cname, oname)
85
        r = self.post(url, content_type='', HTTP_X_OBJECT_PUBLIC='true')
86
        self.assertEqual(r.status_code, 202)
87

    
88
        self._assert_public_object(cname, oname, odata)
89

    
90
    def test_set_twice(self):
91
        cname = get_random_name()
92
        self.create_container(cname)
93
        oname, odata = self.upload_object(cname)[:-1]
94
        self._assert_not_public_object(cname, oname)
95

    
96
        # set public
97
        url = join_urls(self.pithos_path, self.user, cname, oname)
98
        r = self.post(url, content_type='', HTTP_X_OBJECT_PUBLIC='true')
99
        self.assertEqual(r.status_code, 202)
100

    
101
        public = self._assert_public_object(cname, oname, odata)
102

    
103
        # set public
104
        url = join_urls(self.pithos_path, self.user, cname, oname)
105
        r = self.post(url, content_type='', HTTP_X_OBJECT_PUBLIC='true')
106
        self.assertEqual(r.status_code, 202)
107

    
108
        public2 = self._assert_public_object(cname, oname, odata)
109

    
110
        self.assertEqual(public, public2)
111

    
112
    def test_set_unset_set(self):
113
        cname = get_random_name()
114
        self.create_container(cname)
115
        oname, odata = self.upload_object(cname)[:-1]
116
        self._assert_not_public_object(cname, oname)
117

    
118
        # set public
119
        url = join_urls(self.pithos_path, self.user, cname, oname)
120
        r = self.post(url, content_type='', HTTP_X_OBJECT_PUBLIC='true')
121
        self.assertEqual(r.status_code, 202)
122

    
123
        public = self._assert_public_object(cname, oname, odata)
124

    
125
        # unset public
126
        url = join_urls(self.pithos_path, self.user, cname, oname)
127
        r = self.post(url, content_type='', HTTP_X_OBJECT_PUBLIC='false')
128
        self.assertEqual(r.status_code, 202)
129

    
130
        self._assert_not_public_object(cname, oname)
131

    
132
        # set public
133
        url = join_urls(self.pithos_path, self.user, cname, oname)
134
        r = self.post(url, content_type='', HTTP_X_OBJECT_PUBLIC='true')
135
        self.assertEqual(r.status_code, 202)
136

    
137
        public2 = self._assert_public_object(cname, oname, odata)
138

    
139
        self.assertTrue(public != public2)
140

    
141
        # unset public
142
        url = join_urls(self.pithos_path, self.user, cname, oname)
143
        r = self.post(url, content_type='', HTTP_X_OBJECT_PUBLIC='false')
144
        self.assertEqual(r.status_code, 202)
145

    
146
        self._assert_not_public_object(cname, oname)
147

    
148
    def test_update_public_object(self):
149
        cname = get_random_name()
150
        self.create_container(cname)
151
        oname, odata = self.upload_object(cname)[:-1]
152
        self._assert_not_public_object(cname, oname)
153

    
154
        # set public
155
        url = join_urls(self.pithos_path, self.user, cname, oname)
156
        r = self.post(url, content_type='', HTTP_X_OBJECT_PUBLIC='true')
157
        self.assertEqual(r.status_code, 202)
158

    
159
        public = self._assert_public_object(cname, oname, odata)
160

    
161
        odata2 = self.append_object_data(cname, oname)[1]
162

    
163
        public2 = self._assert_public_object(cname, oname, odata + odata2)
164

    
165
        self.assertTrue(public == public2)
166

    
167
    def test_delete_public_object(self):
168
        cname = get_random_name()
169
        self.create_container(cname)
170
        oname, odata = self.upload_object(cname)[:-1]
171
        self._assert_not_public_object(cname, oname)
172

    
173
        # set public
174
        url = join_urls(self.pithos_path, self.user, cname, oname)
175
        r = self.post(url, content_type='', HTTP_X_OBJECT_PUBLIC='true')
176
        self.assertEqual(r.status_code, 202)
177
        public = self._assert_public_object(cname, oname, odata)
178

    
179
        # delete object
180
        r = self.delete(url)
181
        self.assertEqual(r.status_code, 204)
182
        r = self.get(url)
183
        self.assertEqual(r.status_code, 404)
184
        r = self.get(public)
185
        self.assertEqual(r.status_code, 404)
186

    
187
    def test_delete_public_object_history(self):
188
        cname = get_random_name()
189
        self.create_container(cname)
190
        oname, odata = self.upload_object(cname)[:-1]
191
        self._assert_not_public_object(cname, oname)
192

    
193
        # set public
194
        url = join_urls(self.pithos_path, self.user, cname, oname)
195
        r = self.post(url, content_type='', HTTP_X_OBJECT_PUBLIC='true')
196
        self.assertEqual(r.status_code, 202)
197
        public = self._assert_public_object(cname, oname, odata)
198

    
199
        for _ in range(random.randint(1, 10)):
200
            odata += self.append_object_data(cname, oname)[1]
201
            _time.sleep(1)
202

    
203
        # get object versions
204
        url = join_urls(self.pithos_path, self.user, cname, oname)
205
        r = self.get('%s?version=list&format=json' % url)
206
        version_list = json.loads(r.content)['versions']
207
        mtime = [int(float(t[1])) for t in version_list]
208

    
209
        # delete object history
210
        i = random.randrange(len(mtime))
211
        self.delete('%s?until=%d' % (url, mtime[i]))
212
        public2 = self._assert_public_object(cname, oname, odata)
213
        self.assertEqual(public, public2)
214

    
215
        # delete object history until now
216
        _time.sleep(1)
217
        t = datetime.datetime.utcnow()
218
        now = int(_time.mktime(t.timetuple()))
219
        r = self.delete('%s?intil=%d' % (url, now))
220
        self.assertEqual(r.status_code, 204)
221
        r = self.get(url)
222
        self.assertEqual(r.status_code, 404)
223
        r = self.get(public)
224
        self.assertEqual(r.status_code, 404)
225

    
226
    def test_public_manifest(self):
227
        cname = self.create_container()[0]
228
        prefix = 'myobject/'
229
        data = ''
230
        for i in range(random.randint(2, 10)):
231
            part = '%s%d' % (prefix, i)
232
            data += self.upload_object(cname, oname=part)[1]
233

    
234
        manifest = '%s/%s' % (cname, prefix)
235
        oname = get_random_name()
236
        url = join_urls(self.pithos_path, self.user, cname, oname)
237
        r = self.put(url, data='', HTTP_X_OBJECT_MANIFEST=manifest,
238
                     HTTP_X_OBJECT_PUBLIC='true')
239
        self.assertEqual(r.status_code, 201)
240

    
241
        r = self.head(url)
242
        self.assertTrue('X-Object-Manifest' in r)
243
        self.assertEqual(r['X-Object-Manifest'], manifest)
244

    
245
        self.assertTrue('X-Object-Public' in r)
246
        public = r['X-Object-Public']
247

    
248
        r = self.get(public)
249
        self.assertTrue(r.content, data)
250
        #self.assertTrue('X-Object-Manifest' in r)
251
        #self.assertEqual(r['X-Object-Manifest'], manifest)