Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / tests / api.py @ 671e4232

History | View | Annotate | Download (31.5 kB)

1
# Copyright 2011, 2012, 2013 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
from astakos.im.tests.common import *
35
from astakos.im.settings import astakos_services, BASE_HOST
36
from astakos.oa2.backends import DjangoBackend
37

    
38
from synnefo.lib.services import get_service_path
39
from synnefo.lib import join_urls
40

    
41
from django.core.urlresolvers import reverse
42

    
43
from datetime import date
44

    
45
#from xml.dom import minidom
46

    
47
import json
48
import time
49

    
50
ROOT = "/%s/%s/%s/" % (
51
    astakos_settings.BASE_PATH, astakos_settings.ACCOUNTS_PREFIX, 'v1.0')
52
u = lambda url: ROOT + url
53

    
54

    
55
class QuotaAPITest(TestCase):
56
    def test_0(self):
57
        client = Client()
58
        backend = activation_backends.get_backend()
59

    
60
        component1 = Component.objects.create(name="comp1")
61
        register.add_service(component1, "service1", "type1", [])
62
        # custom service resources
63
        resource11 = {"name": "service1.resource11",
64
                      "desc": "resource11 desc",
65
                      "service_type": "type1",
66
                      "service_origin": "service1",
67
                      "ui_visible": True}
68
        r, _ = register.add_resource(resource11)
69
        register.update_resources([(r, 100)])
70
        resource12 = {"name": "service1.resource12",
71
                      "desc": "resource11 desc",
72
                      "service_type": "type1",
73
                      "service_origin": "service1",
74
                      "unit": "bytes"}
75
        r, _ = register.add_resource(resource12)
76
        register.update_resources([(r, 1024)])
77

    
78
        # create user
79
        user = get_local_user('test@grnet.gr')
80
        backend.accept_user(user)
81
        non_moderated_user = get_local_user('nonmon@example.com',
82
                                            is_active=False)
83
        r_user = get_local_user('rej@example.com',
84
                                is_active=False, email_verified=True)
85
        backend.reject_user(r_user, "reason")
86

    
87
        component2 = Component.objects.create(name="comp2")
88
        register.add_service(component2, "service2", "type2", [])
89
        # create another service
90
        resource21 = {"name": "service2.resource21",
91
                      "desc": "resource11 desc",
92
                      "service_type": "type2",
93
                      "service_origin": "service2",
94
                      "ui_visible": False}
95
        r, _ = register.add_resource(resource21)
96
        register.update_resources([(r, 3)])
97

    
98
        resource_names = [r['name'] for r in
99
                          [resource11, resource12, resource21]]
100

    
101
        # get resources
102
        r = client.get(u('resources'))
103
        self.assertEqual(r.status_code, 200)
104
        body = json.loads(r.content)
105
        for name in resource_names:
106
            assertIn(name, body)
107

    
108
        # get quota
109
        r = client.get(u('quotas'))
110
        self.assertEqual(r.status_code, 401)
111

    
112
        headers = {'HTTP_X_AUTH_TOKEN': user.auth_token}
113
        r = client.get(u('quotas/'), **headers)
114
        self.assertEqual(r.status_code, 200)
115
        body = json.loads(r.content)
116
        system_quota = body['system']
117
        assertIn('system', body)
118
        for name in resource_names:
119
            assertIn(name, system_quota)
120

    
121
        nmheaders = {'HTTP_X_AUTH_TOKEN': non_moderated_user.auth_token}
122
        r = client.get(u('quotas/'), **nmheaders)
123
        self.assertEqual(r.status_code, 401)
124

    
125
        q = quotas.get_user_quotas(non_moderated_user)
126
        self.assertEqual(q, {})
127

    
128
        q = quotas.get_user_quotas(r_user)
129
        self.assertEqual(q, {})
130

    
131
        r = client.get(u('service_quotas'))
132
        self.assertEqual(r.status_code, 401)
133

    
134
        s1_headers = {'HTTP_X_AUTH_TOKEN': component1.auth_token}
135
        r = client.get(u('service_quotas'), **s1_headers)
136
        self.assertEqual(r.status_code, 200)
137
        body = json.loads(r.content)
138
        assertIn(user.uuid, body)
139

    
140
        r = client.get(u('commissions'), **s1_headers)
141
        self.assertEqual(r.status_code, 200)
142
        body = json.loads(r.content)
143
        self.assertEqual(body, [])
144

    
145
        # issue some commissions
146
        commission_request = {
147
            "force": False,
148
            "auto_accept": False,
149
            "name": "my commission",
150
            "provisions": [
151
                {
152
                    "holder": user.uuid,
153
                    "source": "system",
154
                    "resource": resource11['name'],
155
                    "quantity": 1
156
                },
157
                {
158
                    "holder": user.uuid,
159
                    "source": "system",
160
                    "resource": resource12['name'],
161
                    "quantity": 30000
162
                }]}
163

    
164
        post_data = json.dumps(commission_request)
165
        r = client.post(u('commissions'), post_data,
166
                        content_type='application/json', **s1_headers)
167
        self.assertEqual(r.status_code, 413)
168

    
169
        commission_request = {
170
            "force": False,
171
            "auto_accept": False,
172
            "name": "my commission",
173
            "provisions": [
174
                {
175
                    "holder": user.uuid,
176
                    "source": "system",
177
                    "resource": resource11['name'],
178
                    "quantity": 1
179
                },
180
                {
181
                    "holder": user.uuid,
182
                    "source": "system",
183
                    "resource": resource12['name'],
184
                    "quantity": 100
185
                }]}
186

    
187
        post_data = json.dumps(commission_request)
188
        r = client.post(u('commissions'), post_data,
189
                        content_type='application/json', **s1_headers)
190
        self.assertEqual(r.status_code, 201)
191
        body = json.loads(r.content)
192
        serial1 = body['serial']
193
        assertGreater(serial1, 0)
194

    
195
        post_data = json.dumps(commission_request)
196
        r = client.post(u('commissions'), post_data,
197
                        content_type='application/json', **s1_headers)
198
        self.assertEqual(r.status_code, 201)
199
        body = json.loads(r.content)
200
        serial2 = body['serial']
201
        assertGreater(serial2, serial1)
202

    
203
        post_data = json.dumps(commission_request)
204
        r = client.post(u('commissions'), post_data,
205
                        content_type='application/json', **s1_headers)
206
        self.assertEqual(r.status_code, 201)
207
        body = json.loads(r.content)
208
        serial3 = body['serial']
209
        assertGreater(serial3, serial2)
210

    
211
        r = client.get(u('commissions'), **s1_headers)
212
        self.assertEqual(r.status_code, 200)
213
        body = json.loads(r.content)
214
        self.assertEqual(len(body), 3)
215

    
216
        r = client.get(u('commissions/' + str(serial1)), **s1_headers)
217
        self.assertEqual(r.status_code, 200)
218
        body = json.loads(r.content)
219
        self.assertEqual(body['serial'], serial1)
220
        assertIn('issue_time', body)
221
        provisions = sorted(body['provisions'], key=lambda p: p['resource'])
222
        self.assertEqual(provisions, commission_request['provisions'])
223
        self.assertEqual(body['name'], commission_request['name'])
224

    
225
        r = client.get(u('service_quotas?user=' + user.uuid), **s1_headers)
226
        self.assertEqual(r.status_code, 200)
227
        body = json.loads(r.content)
228
        user_quota = body[user.uuid]
229
        system_quota = user_quota['system']
230
        r11 = system_quota[resource11['name']]
231
        self.assertEqual(r11['usage'], 3)
232
        self.assertEqual(r11['pending'], 3)
233

    
234
        # resolve pending commissions
235
        resolve_data = {
236
            "accept": [serial1, serial3],
237
            "reject": [serial2, serial3, serial3 + 1],
238
        }
239
        post_data = json.dumps(resolve_data)
240

    
241
        r = client.post(u('commissions/action'), post_data,
242
                        content_type='application/json', **s1_headers)
243
        self.assertEqual(r.status_code, 200)
244
        body = json.loads(r.content)
245
        self.assertEqual(body['accepted'], [serial1])
246
        self.assertEqual(body['rejected'], [serial2])
247
        failed = body['failed']
248
        self.assertEqual(len(failed), 2)
249

    
250
        r = client.get(u('commissions/' + str(serial1)), **s1_headers)
251
        self.assertEqual(r.status_code, 404)
252

    
253
        # auto accept
254
        commission_request = {
255
            "auto_accept": True,
256
            "name": "my commission",
257
            "provisions": [
258
                {
259
                    "holder": user.uuid,
260
                    "source": "system",
261
                    "resource": resource11['name'],
262
                    "quantity": 1
263
                },
264
                {
265
                    "holder": user.uuid,
266
                    "source": "system",
267
                    "resource": resource12['name'],
268
                    "quantity": 100
269
                }]}
270

    
271
        post_data = json.dumps(commission_request)
272
        r = client.post(u('commissions'), post_data,
273
                        content_type='application/json', **s1_headers)
274
        self.assertEqual(r.status_code, 201)
275
        body = json.loads(r.content)
276
        serial4 = body['serial']
277
        assertGreater(serial4, serial3)
278

    
279
        r = client.get(u('commissions/' + str(serial4)), **s1_headers)
280
        self.assertEqual(r.status_code, 404)
281

    
282
        # malformed
283
        commission_request = {
284
            "auto_accept": True,
285
            "name": "my commission",
286
            "provisions": [
287
                {
288
                    "holder": user.uuid,
289
                    "source": "system",
290
                    "resource": resource11['name'],
291
                }
292
            ]}
293

    
294
        post_data = json.dumps(commission_request)
295
        r = client.post(u('commissions'), post_data,
296
                        content_type='application/json', **s1_headers)
297
        self.assertEqual(r.status_code, 400)
298

    
299
        commission_request = {
300
            "auto_accept": True,
301
            "name": "my commission",
302
            "provisions": "dummy"}
303

    
304
        post_data = json.dumps(commission_request)
305
        r = client.post(u('commissions'), post_data,
306
                        content_type='application/json', **s1_headers)
307
        self.assertEqual(r.status_code, 400)
308

    
309
        r = client.post(u('commissions'), commission_request,
310
                        content_type='application/json', **s1_headers)
311
        self.assertEqual(r.status_code, 400)
312

    
313
        # no holding
314
        commission_request = {
315
            "auto_accept": True,
316
            "name": "my commission",
317
            "provisions": [
318
                {
319
                    "holder": user.uuid,
320
                    "source": "system",
321
                    "resource": "non existent",
322
                    "quantity": 1
323
                },
324
                {
325
                    "holder": user.uuid,
326
                    "source": "system",
327
                    "resource": resource12['name'],
328
                    "quantity": 100
329
                }]}
330

    
331
        post_data = json.dumps(commission_request)
332
        r = client.post(u('commissions'), post_data,
333
                        content_type='application/json', **s1_headers)
334
        self.assertEqual(r.status_code, 404)
335

    
336
        # release
337
        commission_request = {
338
            "provisions": [
339
                {
340
                    "holder": user.uuid,
341
                    "source": "system",
342
                    "resource": resource11['name'],
343
                    "quantity": -1
344
                }
345
            ]}
346

    
347
        post_data = json.dumps(commission_request)
348
        r = client.post(u('commissions'), post_data,
349
                        content_type='application/json', **s1_headers)
350
        self.assertEqual(r.status_code, 201)
351
        body = json.loads(r.content)
352
        serial = body['serial']
353

    
354
        accept_data = {'accept': ""}
355
        post_data = json.dumps(accept_data)
356
        r = client.post(u('commissions/' + str(serial) + '/action'), post_data,
357
                        content_type='application/json', **s1_headers)
358
        self.assertEqual(r.status_code, 200)
359

    
360
        reject_data = {'reject': ""}
361
        post_data = json.dumps(accept_data)
362
        r = client.post(u('commissions/' + str(serial) + '/action'), post_data,
363
                        content_type='application/json', **s1_headers)
364
        self.assertEqual(r.status_code, 404)
365

    
366
        # force
367
        commission_request = {
368
            "force": True,
369
            "provisions": [
370
                {
371
                    "holder": user.uuid,
372
                    "source": "system",
373
                    "resource": resource11['name'],
374
                    "quantity": 100
375
                }]}
376

    
377
        post_data = json.dumps(commission_request)
378
        r = client.post(u('commissions'), post_data,
379
                        content_type='application/json', **s1_headers)
380
        self.assertEqual(r.status_code, 201)
381

    
382
        commission_request = {
383
            "force": True,
384
            "provisions": [
385
                {
386
                    "holder": user.uuid,
387
                    "source": "system",
388
                    "resource": resource11['name'],
389
                    "quantity": -200
390
                }]}
391

    
392
        post_data = json.dumps(commission_request)
393
        r = client.post(u('commissions'), post_data,
394
                        content_type='application/json', **s1_headers)
395
        self.assertEqual(r.status_code, 413)
396

    
397
        r = client.get(u('quotas'), **headers)
398
        self.assertEqual(r.status_code, 200)
399
        body = json.loads(r.content)
400
        system_quota = body['system']
401
        r11 = system_quota[resource11['name']]
402
        self.assertEqual(r11['usage'], 102)
403
        self.assertEqual(r11['pending'], 101)
404

    
405
        # Bad Request
406
        r = client.head(u('commissions'))
407
        self.assertEqual(r.status_code, 405)
408
        self.assertTrue('Allow' in r)
409

    
410

    
411
class TokensApiTest(TestCase):
412
    def setUp(self):
413
        backend = activation_backends.get_backend()
414

    
415
        self.user1 = get_local_user(
416
            'test1@example.org', email_verified=True, moderated=True,
417
            is_rejected=False)
418
        backend.activate_user(self.user1)
419
        assert self.user1.is_active is True
420

    
421
        self.user2 = get_local_user(
422
            'test2@example.org', email_verified=True, moderated=True,
423
            is_rejected=False)
424
        backend.activate_user(self.user2)
425
        assert self.user2.is_active is True
426

    
427
        c1 = Component(name='component1', url='http://localhost/component1')
428
        c1.save()
429
        s1 = Service(component=c1, type='type1', name='service1')
430
        s1.save()
431
        e1 = Endpoint(service=s1)
432
        e1.save()
433
        e1.data.create(key='versionId', value='v1.0')
434
        e1.data.create(key='publicURL', value='http://localhost:8000/s1/v1.0')
435

    
436
        s2 = Service(component=c1, type='type2', name='service2')
437
        s2.save()
438
        e2 = Endpoint(service=s2)
439
        e2.save()
440
        e2.data.create(key='versionId', value='v1.0')
441
        e2.data.create(key='publicURL', value='http://localhost:8000/s2/v1.0')
442

    
443
        c2 = Component(name='component2', url='http://localhost/component2')
444
        c2.save()
445
        s3 = Service(component=c2, type='type3', name='service3')
446
        s3.save()
447
        e3 = Endpoint(service=s3)
448
        e3.save()
449
        e3.data.create(key='versionId', value='v2.0')
450
        e3.data.create(key='publicURL', value='http://localhost:8000/s3/v2.0')
451

    
452
        oa2_backend = DjangoBackend()
453
        self.token = oa2_backend.token_model.create(
454
            code='12345',
455
            expires_at=datetime.now() + timedelta(seconds=5),
456
            user=self.user1,
457
            client=oa2_backend.client_model.create(type='public'),
458
            redirect_uri='https://server.com/handle_code')
459

    
460
    def test_authenticate(self):
461
        client = Client()
462
        url = reverse('astakos.api.tokens.authenticate')
463

    
464
        # Check not allowed method
465
        r = client.get(url, post_data={})
466
        self.assertEqual(r.status_code, 405)
467
        self.assertTrue('Allow' in r)
468
        self.assertEqual(r['Allow'], 'POST')
469

    
470
        # check public mode
471
        r = client.post(url, CONTENT_LENGTH=0)
472
        self.assertEqual(r.status_code, 200)
473
        self.assertTrue(r['Content-Type'].startswith('application/json'))
474
        try:
475
            body = json.loads(r.content)
476
        except Exception, e:
477
            self.fail(e)
478
        self.assertTrue('token' not in body.get('access'))
479
        self.assertTrue('user' not in body.get('access'))
480
        self.assertTrue('serviceCatalog' in body.get('access'))
481

    
482
        # Check unsupported xml input
483
        post_data = """
484
            <?xml version="1.0" encoding="UTF-8"?>
485
                <auth xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
486
                 xmlns="http://docs.openstack.org/identity/api/v2.0"
487
                 tenantName="%s">
488
                  <passwordCredentials username="%s" password="%s"/>
489
                </auth>""" % (self.user1.uuid, self.user1.uuid,
490
                              self.user1.auth_token)
491
        r = client.post(url, post_data, content_type='application/xml')
492
        self.assertEqual(r.status_code, 400)
493
        body = json.loads(r.content)
494
        self.assertEqual(body['badRequest']['message'],
495
                         "Unsupported Content-type: 'application/xml'")
496

    
497
        # Check malformed request: missing password
498
        post_data = """{"auth":{"passwordCredentials":{"username":"%s"},
499
                                "tenantName":"%s"}}""" % (
500
            self.user1.uuid, self.user1.uuid)
501
        r = client.post(url, post_data, content_type='application/json')
502
        self.assertEqual(r.status_code, 400)
503
        body = json.loads(r.content)
504
        self.assertTrue(body['badRequest']['message'].
505
                        startswith('Malformed request'))
506

    
507
        # Check malformed request: missing username
508
        post_data = """{"auth":{"passwordCredentials":{"password":"%s"},
509
                                "tenantName":"%s"}}""" % (
510
            self.user1.auth_token, self.user1.uuid)
511
        r = client.post(url, post_data, content_type='application/json')
512
        self.assertEqual(r.status_code, 400)
513
        body = json.loads(r.content)
514
        self.assertTrue(body['badRequest']['message'].
515
                        startswith('Malformed request'))
516

    
517
        # Check invalid pass
518
        post_data = """{"auth":{"passwordCredentials":{"username":"%s",
519
                                                       "password":"%s"},
520
                                "tenantName":"%s"}}""" % (
521
            self.user1.uuid, '', self.user1.uuid)
522
        r = client.post(url, post_data, content_type='application/json')
523
        self.assertEqual(r.status_code, 401)
524
        body = json.loads(r.content)
525
        self.assertEqual(body['unauthorized']['message'],
526
                         'Invalid token')
527

    
528
        # Check inconsistent pass
529
        post_data = """{"auth":{"passwordCredentials":{"username":"%s",
530
                                                       "password":"%s"},
531
                                "tenantName":"%s"}}""" % (
532
            self.user1.uuid, self.user2.auth_token, self.user2.uuid)
533
        r = client.post(url, post_data, content_type='application/json')
534
        self.assertEqual(r.status_code, 401)
535
        body = json.loads(r.content)
536
        self.assertEqual(body['unauthorized']['message'],
537
                         'Invalid credentials')
538

    
539
        # Check invalid json data
540
        r = client.post(url, "not json", content_type='application/json')
541
        self.assertEqual(r.status_code, 400)
542
        body = json.loads(r.content)
543
        self.assertEqual(body['badRequest']['message'], 'Invalid JSON data')
544

    
545
        # Check auth with token
546
        post_data = """{"auth":{"token": {"id":"%s"},
547
                        "tenantName":"%s"}}""" % (
548
            self.user1.auth_token, self.user1.uuid)
549
        r = client.post(url, post_data, content_type='application/json')
550
        self.assertEqual(r.status_code, 200)
551
        self.assertTrue(r['Content-Type'].startswith('application/json'))
552
        try:
553
            body = json.loads(r.content)
554
        except Exception, e:
555
            self.fail(e)
556

    
557
        # Check malformed request: missing token
558
        post_data = """{"auth":{"auth_token":{"id":"%s"},
559
                                "tenantName":"%s"}}""" % (
560
            self.user1.auth_token, self.user1.uuid)
561
        r = client.post(url, post_data, content_type='application/json')
562
        self.assertEqual(r.status_code, 400)
563
        body = json.loads(r.content)
564
        self.assertTrue(body['badRequest']['message'].
565
                        startswith('Malformed request'))
566

    
567
        # Check bad request: inconsistent tenant
568
        post_data = """{"auth":{"token":{"id":"%s"},
569
                                "tenantName":"%s"}}""" % (
570
            self.user1.auth_token, self.user2.uuid)
571
        r = client.post(url, post_data, content_type='application/json')
572
        self.assertEqual(r.status_code, 400)
573
        body = json.loads(r.content)
574
        self.assertEqual(body['badRequest']['message'],
575
                         'Not conforming tenantName')
576

    
577
        # Check bad request: inconsistent tenant
578
        post_data = """{"auth":{"token":{"id":"%s"},
579
                                "tenantName":""}}""" % (
580
            self.user1.auth_token)
581
        r = client.post(url, post_data, content_type='application/json')
582
        self.assertEqual(r.status_code, 200)
583

    
584
        # Check successful json response: user credential auth
585
        post_data = """{"auth":{"passwordCredentials":{"username":"%s",
586
                                                       "password":"%s"},
587
                                "tenantName":"%s"}}""" % (
588
            self.user1.uuid, self.user1.auth_token, self.user1.uuid)
589
        r = client.post(url, post_data, content_type='application/json')
590
        self.assertEqual(r.status_code, 200)
591
        self.assertTrue(r['Content-Type'].startswith('application/json'))
592
        try:
593
            body = json.loads(r.content)
594
        except Exception, e:
595
            self.fail(e)
596

    
597
        try:
598
            token = body['access']['token']['id']
599
            user = body['access']['user']['id']
600
            service_catalog = body['access']['serviceCatalog']
601
        except KeyError:
602
            self.fail('Invalid response')
603

    
604
        self.assertEqual(token, self.user1.auth_token)
605
        self.assertEqual(user, self.user1.uuid)
606
        self.assertEqual(len(service_catalog), 3)
607

    
608
        # Check successful json response: token auth
609
        post_data = """{"auth":{"token":{"id":"%s"},
610
                                "tenantName":"%s"}}""" % (
611
            self.user1.auth_token, self.user1.uuid)
612
        r = client.post(url, post_data, content_type='application/json')
613
        self.assertEqual(r.status_code, 200)
614
        self.assertTrue(r['Content-Type'].startswith('application/json'))
615
        try:
616
            body = json.loads(r.content)
617
        except Exception, e:
618
            self.fail(e)
619

    
620
        try:
621
            token = body['access']['token']['id']
622
            user = body['access']['user']['id']
623
            service_catalog = body['access']['serviceCatalog']
624
        except KeyError:
625
            self.fail('Invalid response')
626

    
627
        self.assertEqual(token, self.user1.auth_token)
628
        self.assertEqual(user, self.user1.uuid)
629
        self.assertEqual(len(service_catalog), 3)
630

    
631
        # Check successful xml response
632
        headers = {'HTTP_ACCEPT': 'application/xml'}
633
        post_data = """{"auth":{"passwordCredentials":{"username":"%s",
634
                                                       "password":"%s"},
635
                                "tenantName":"%s"}}""" % (
636
            self.user1.uuid, self.user1.auth_token, self.user1.uuid)
637
        r = client.post(url, post_data, content_type='application/json',
638
                        **headers)
639
        self.assertEqual(r.status_code, 200)
640
        self.assertTrue(r['Content-Type'].startswith('application/xml'))
641
#        try:
642
#            body = minidom.parseString(r.content)
643
#        except Exception, e:
644
#            self.fail(e)
645

    
646
        # oath access token authorization
647
        post_data = """{"auth":{"token":{"id":"%s"},
648
                                "tenantName":"%s"}}""" % (
649
            self.token.code, self.user1.uuid)
650
        r = client.post(url, post_data, content_type='application/json')
651
        self.assertEqual(r.status_code, 401)
652

    
653

    
654
class UserCatalogsTest(TestCase):
655
    def test_get_uuid_displayname_catalogs(self):
656
        self.user = get_local_user(
657
            'test1@example.org', email_verified=True, moderated=True,
658
            is_rejected=False, is_active=False)
659

    
660
        client = Client()
661
        url = reverse('astakos.api.user.get_uuid_displayname_catalogs')
662
        d = dict(uuids=[self.user.uuid], displaynames=[self.user.username])
663

    
664
        # assert Unauthorized: missing authentication token
665
        r = client.post(url,
666
                        data=json.dumps(d),
667
                        content_type='application/json')
668
        self.assertEqual(r.status_code, 401)
669

    
670
        # assert Unauthorized: invalid authentication token
671
        r = client.post(url,
672
                        data=json.dumps(d),
673
                        content_type='application/json',
674
                        HTTP_X_AUTH_TOKEN='1234')
675
        self.assertEqual(r.status_code, 401)
676

    
677
        # assert Unauthorized: inactive token holder
678
        r = client.post(url,
679
                        data=json.dumps(d),
680
                        content_type='application/json',
681
                        HTTP_X_AUTH_TOKEN=self.user.auth_token)
682
        self.assertEqual(r.status_code, 401)
683

    
684
        backend = activation_backends.get_backend()
685
        backend.activate_user(self.user)
686
        assert self.user.is_active is True
687

    
688
        r = client.post(url,
689
                        data=json.dumps(d),
690
                        content_type='application/json',
691
                        HTTP_X_AUTH_TOKEN=self.user.auth_token)
692
        self.assertEqual(r.status_code, 200)
693
        try:
694
            data = json.loads(r.content)
695
        except:
696
            self.fail('Response body should be json formatted')
697
        else:
698
            if not isinstance(data, dict):
699
                self.fail('Response body should be json formatted dictionary')
700

    
701
            self.assertTrue('uuid_catalog' in data)
702
            self.assertEqual(data['uuid_catalog'],
703
                             {self.user.uuid: self.user.username})
704

    
705
            self.assertTrue('displayname_catalog' in data)
706
            self.assertEqual(data['displayname_catalog'],
707
                             {self.user.username: self.user.uuid})
708

    
709
        # assert Unauthorized: expired token
710
        self.user.auth_token_expires = date.today() - timedelta(1)
711
        self.user.save()
712

    
713
        r = client.post(url,
714
                        data=json.dumps(d),
715
                        content_type='application/json',
716
                        HTTP_X_AUTH_TOKEN=self.user.auth_token)
717
        self.assertEqual(r.status_code, 401)
718

    
719
        # assert Unauthorized: expired token
720
        self.user.auth_token_expires = date.today() + timedelta(1)
721
        self.user.save()
722

    
723
        # assert badRequest
724
        r = client.post(url,
725
                        data=json.dumps(str(d)),
726
                        content_type='application/json',
727
                        HTTP_X_AUTH_TOKEN=self.user.auth_token)
728
        self.assertEqual(r.status_code, 400)
729

    
730

    
731
class WrongPathAPITest(TestCase):
732
    def test_catch_wrong_account_paths(self, *args):
733
        path = get_service_path(astakos_services, 'account', 'v1.0')
734
        path = join_urls(BASE_HOST, path, 'nonexistent')
735
        response = self.client.get(path)
736
        self.assertEqual(response.status_code, 400)
737
        try:
738
            error = json.loads(response.content)
739
        except ValueError:
740
            self.assertTrue(False)
741

    
742
    def test_catch_wrong_identity_paths(self, *args):
743
        path = get_service_path(astakos_services, 'identity', 'v2.0')
744
        path = join_urls(BASE_HOST, path, 'nonexistent')
745
        response = self.client.get(path)
746
        self.assertEqual(response.status_code, 400)
747
        try:
748
            json.loads(response.content)
749
        except ValueError:
750
            self.assertTrue(False)
751

    
752

    
753
class ValidateAccessToken(TestCase):
754
    def setUp(self):
755
        self.oa2_backend = DjangoBackend()
756
        self.user = AstakosUser.objects.create(username="user@synnefo.org")
757
        self.token = self.oa2_backend.token_model.create(
758
            code='12345',
759
            expires_at=datetime.now() + timedelta(seconds=5),
760
            user=self.user,
761
            client=self.oa2_backend.client_model.create(type='public'),
762
            redirect_uri='https://server.com/handle_code',
763
            scope='user-scope')
764

    
765
    def test_validate_token(self):
766
        # invalid token
767
        url = reverse('astakos.api.tokens.validate_token',
768
                      kwargs={'token_id': 'invalid'})
769
        r = self.client.get(url)
770
        self.assertEqual(r.status_code, 404)
771

    
772
        # valid token
773
        url = reverse('astakos.api.tokens.validate_token',
774
                      kwargs={'token_id': self.token.code})
775

    
776
        r = self.client.head(url)
777
        self.assertEqual(r.status_code, 400)
778
        r = self.client.put(url)
779
        self.assertEqual(r.status_code, 400)
780
        r = self.client.post(url)
781
        self.assertEqual(r.status_code, 400)
782

    
783
        r = self.client.get(url)
784
        self.assertEqual(r.status_code, 200)
785
        self.assertTrue(r['Content-Type'].startswith('application/json'))
786
        try:
787
            body = json.loads(r.content)
788
            user = body['access']['user']['id']
789
            self.assertEqual(user, self.user.uuid)
790
        except Exception:
791
            self.fail('Unexpected response content')
792

    
793
        # inconsistent belongsTo parameter
794
        r = self.client.get('%s?belongsTo=invalid' % url)
795
        self.assertEqual(r.status_code, 404)
796

    
797
        # consistent belongsTo parameter
798
        r = self.client.get('%s?belongsTo=%s' % (url, self.token.scope))
799
        self.assertEqual(r.status_code, 200)
800
        self.assertTrue(r['Content-Type'].startswith('application/json'))
801
        try:
802
            body = json.loads(r.content)
803
            user = body['access']['user']['id']
804
            self.assertEqual(user, self.user.uuid)
805
        except Exception:
806
            self.fail('Unexpected response content')
807

    
808
        # expired token
809
        sleep_time = (self.token.expires_at - datetime.now()).total_seconds()
810
        time.sleep(max(sleep_time, 0))
811
        r = self.client.get(url)
812
        self.assertEqual(r.status_code, 404)
813
        # assert expired token has been deleted
814
        self.assertEqual(self.oa2_backend.token_model.count(), 0)
815

    
816
        # user authentication token
817
        url = reverse('astakos.api.tokens.validate_token',
818
                      kwargs={'token_id': self.user.auth_token})
819
        self.assertEqual(r.status_code, 404)