Revision 381a548c

b/snf-astakos-app/astakos/api/projects.py
266 266
        return get_projects(request)
267 267
    elif method == "POST":
268 268
        return create_project(request)
269
    return api.api_method_not_allowed(request)
269
    return api.api_method_not_allowed(request, allowed_methods=['GET', 'POST'])
270 270

  
271 271

  
272 272
@api.api_method(http_method="GET", token_required=True, user_required=False)
......
314 314
        return get_project(request, project_id)
315 315
    if method == "POST":
316 316
        return modify_project(request, project_id)
317
    return api.api_method_not_allowed(request)
317
    return api.api_method_not_allowed(request, allowed_methods=['GET', 'POST'])
318 318

  
319 319

  
320 320
@api.api_method(http_method="GET", token_required=True, user_required=False)
......
483 483
    method = request.method
484 484
    if method == "GET":
485 485
        return get_applications(request)
486
    return api.api_method_not_allowed(request)
486
    return api.api_method_not_allowed(request, allowed_methods=['GET'])
487 487

  
488 488

  
489 489
def make_application_query(input_data):
......
567 567
        return get_memberships(request)
568 568
    elif method == "POST":
569 569
        return post_memberships(request)
570
    return api.api_method_not_allowed(request)
570
    return api.api_method_not_allowed(request, allowed_methods=['GET', 'POST'])
571 571

  
572 572

  
573 573
def make_membership_query(input_data):
b/snf-astakos-app/astakos/api/quotas.py
82 82
        return get_pending_commissions(request)
83 83
    elif method == 'POST':
84 84
        return issue_commission(request)
85
    return api.api_method_not_allowed(request)
85
    return api.api_method_not_allowed(request, allowed_methods=['GET', 'POST'])
86 86

  
87 87

  
88 88
@api.api_method(http_method='GET', token_required=True, user_required=False)
b/snf-astakos-app/astakos/im/tests/api.py
384 384

  
385 385
        # Bad Request
386 386
        r = client.head(u('commissions'))
387
        self.assertEqual(r.status_code, 400)
387
        self.assertEqual(r.status_code, 405)
388
        self.assertTrue('Allow' in r)
388 389

  
389 390

  
390 391
class TokensApiTest(TestCase):
......
434 435

  
435 436
        # Check not allowed method
436 437
        r = client.get(url, post_data={})
437
        self.assertEqual(r.status_code, 400)
438
        self.assertEqual(r.status_code, 405)
439
        self.assertTrue('Allow' in r)
440
        self.assertEqual(r['Allow'], 'POST')
438 441

  
439 442
        # check public mode
440 443
        r = client.post(url, CONTENT_LENGTH=0)
b/snf-astakos-app/astakos/im/tests/projects.py
488 488

  
489 489
        # Bad requests
490 490
        r = client.head(reverse("api_projects"), **h_admin)
491
        self.assertEqual(r.status_code, 400)
491
        self.assertEqual(r.status_code, 405)
492
        self.assertTrue('Allow' in r)
492 493

  
493 494
        r = client.head(reverse("api_project",
494 495
                                kwargs={"project_id": 1}), **h_admin)
495
        self.assertEqual(r.status_code, 400)
496
        self.assertEqual(r.status_code, 405)
497
        self.assertTrue('Allow' in r)
496 498

  
497 499
        r = client.head(reverse("api_applications"), **h_admin)
498
        self.assertEqual(r.status_code, 400)
500
        self.assertEqual(r.status_code, 405)
501
        self.assertTrue('Allow' in r)
499 502

  
500 503
        r = client.head(reverse("api_memberships"), **h_admin)
501
        self.assertEqual(r.status_code, 400)
504
        self.assertEqual(r.status_code, 405)
505
        self.assertTrue('Allow' in r)
502 506

  
503 507
        status = self.project_action(1, "nonex", h_owner)
504 508
        self.assertEqual(status, 400)
b/snf-cyclades-app/synnefo/api/extensions.py
52 52
    if request.method == 'GET':
53 53
        return list_extensions(request)
54 54
    else:
55
        return api.api_method_not_allowed(request)
55
        return api.api_method_not_allowed(request, allowed_methods=['GET'])
56 56

  
57 57

  
58 58
def demux_extension(request, extension_alias):
59 59
    if request.method == 'GET':
60 60
        return get_extension(request, extension_alias)
61 61
    else:
62
        return api.api_method_not_allowed(request)
62
        return api.api_method_not_allowed(request, allowed_methods=['GET'])
63 63

  
64 64

  
65 65
@api.api_method(http_method='GET', user_required=True, logger=log)
b/snf-cyclades-app/synnefo/api/floating_ips.py
64 64
    elif request.method == 'POST':
65 65
        return allocate_floating_ip(request)
66 66
    else:
67
        return api.api_method_not_allowed(request)
67
        return api.api_method_not_allowed(request,
68
                                          allowed_methods=['GET', 'POST'])
68 69

  
69 70

  
70 71
def floating_ip_demux(request, floating_ip_id):
......
73 74
    elif request.method == 'DELETE':
74 75
        return release_floating_ip(request, floating_ip_id)
75 76
    else:
76
        return api.api_method_not_allowed(request)
77
        return api.api_method_not_allowed(request,
78
                                          allowed_methods=['GET', 'DELETE'])
77 79

  
78 80

  
79 81
def ip_to_dict(floating_ip):
b/snf-cyclades-app/synnefo/api/images.py
65 65
    elif request.method == 'POST':
66 66
        return create_image(request)
67 67
    else:
68
        return api.api_method_not_allowed(request)
68
        return api.api_method_not_allowed(request,
69
                                          allowed_methods=['GET', 'POST'])
69 70

  
70 71

  
71 72
def image_demux(request, image_id):
......
74 75
    elif request.method == 'DELETE':
75 76
        return delete_image(request, image_id)
76 77
    else:
77
        return api.api_method_not_allowed(request)
78
        return api.api_method_not_allowed(request,
79
                                          allowed_methods=['GET', 'DELETE'])
78 80

  
79 81

  
80 82
def metadata_demux(request, image_id):
......
83 85
    elif request.method == 'POST':
84 86
        return update_metadata(request, image_id)
85 87
    else:
86
        return api.api_method_not_allowed(request)
88
        return api.api_method_not_allowed(request,
89
                                          allowed_methods=['GET', 'POST'])
87 90

  
88 91

  
89 92
def metadata_item_demux(request, image_id, key):
......
94 97
    elif request.method == 'DELETE':
95 98
        return delete_metadata_item(request, image_id, key)
96 99
    else:
97
        return api.api_method_not_allowed(request)
100
        return api.api_method_not_allowed(request,
101
                                          allowed_methods=['GET',
102
                                                           'PUT',
103
                                                           'DELETE'])
98 104

  
99 105

  
100 106
def image_to_dict(image, detail=True):
b/snf-cyclades-app/synnefo/api/networks.py
64 64
    elif request.method == 'POST':
65 65
        return create_network(request)
66 66
    else:
67
        return api.api_method_not_allowed(request)
67
        return api.api_method_not_allowed(request,
68
                                          allowed_methods=['GET', 'POST'])
68 69

  
69 70

  
70 71
def network_demux(request, network_id):
......
75 76
    elif request.method == 'DELETE':
76 77
        return delete_network(request, network_id)
77 78
    else:
78
        return api.api_method_not_allowed(request)
79
        return api.api_method_not_allowed(request,
80
                                          allowed_methods=['GET',
81
                                                           'PUT',
82
                                                           'DELETE'])
79 83

  
80 84

  
81 85
def network_to_dict(network, user_id, detail=True):
b/snf-cyclades-app/synnefo/api/servers.py
70 70
    elif request.method == 'POST':
71 71
        return create_server(request)
72 72
    else:
73
        return api.api_method_not_allowed(request)
73
        return api.api_method_not_allowed(request,
74
                                          allowed_methods=['GET', 'POST'])
74 75

  
75 76

  
76 77
def server_demux(request, server_id):
......
81 82
    elif request.method == 'DELETE':
82 83
        return delete_server(request, server_id)
83 84
    else:
84
        return api.api_method_not_allowed(request)
85
        return api.api_method_not_allowed(request,
86
                                          allowed_methods=['GET',
87
                                                           'PUT',
88
                                                           'DELETE'])
85 89

  
86 90

  
87 91
def metadata_demux(request, server_id):
......
90 94
    elif request.method == 'POST':
91 95
        return update_metadata(request, server_id)
92 96
    else:
93
        return api.api_method_not_allowed(request)
97
        return api.api_method_not_allowed(request,
98
                                          allowed_methods=['GET', 'POST'])
94 99

  
95 100

  
96 101
def metadata_item_demux(request, server_id, key):
......
101 106
    elif request.method == 'DELETE':
102 107
        return delete_metadata_item(request, server_id, key)
103 108
    else:
104
        return api.api_method_not_allowed(request)
109
        return api.api_method_not_allowed(request,
110
                                          allowed_methods=['GET',
111
                                                           'PUT',
112
                                                           'DELETE'])
105 113

  
106 114

  
107 115
def nic_to_dict(nic):
b/snf-django-lib/snf_django/lib/api/__init__.py
90 90

  
91 91
                # Check HTTP method
92 92
                if http_method and request.method != http_method:
93
                    raise faults.BadRequest("Method not allowed")
93
                    raise faults.NotAllowed("Method not allowed",
94
                                            allowed_methods=[http_method])
94 95

  
95 96
                # Get authentication token
96 97
                request.x_auth_token = None
......
231 232
        data = json.dumps(d)
232 233

  
233 234
    response = HttpResponse(data, status=fault.code)
235
    if response.status_code == 405 and hasattr(fault, 'allowed_methods'):
236
        response['Allow'] = ','.join(fault.allowed_methods)
234 237
    update_response_headers(request, response)
235 238
    return response
236 239

  
......
241 244

  
242 245

  
243 246
@api_method(token_required=False, user_required=False)
244
def api_method_not_allowed(request):
245
    raise faults.BadRequest('Method not allowed')
247
def api_method_not_allowed(request, allowed_methods):
248
    raise faults.NotAllowed("Method not allowed",
249
                            allowed_methods=allowed_methods)
246 250

  
247 251

  
248 252
def allow_jsonp(key='callback'):
b/snf-django-lib/snf_django/lib/api/faults.py
71 71
    pass
72 72

  
73 73

  
74
class NotAllowed(Fault):
75
    code = 405
76

  
77
    def __init__(self, message='', details='', name='', code=500,
78
                 allowed_methods=None):
79
        """
80
        :param allowed_methods: (list) the valid methods
81
        """
82
        super(NotAllowed, self).__init__(message, details, name, code)
83
        self.allowed_methods = allowed_methods or []
84

  
85

  
74 86
class ItemNotFound(Fault):
75 87
    code = 404
76 88

  
b/snf-django-lib/snf_django/utils/testing.py
256 256
        self.assertFault(response, 404, 'itemNotFound')
257 257

  
258 258
    def assertMethodNotAllowed(self, response):
259
        self.assertFault(response, 400, 'badRequest')
259
        self.assertFault(response, 405, 'notAllowed')
260
        self.assertTrue('Allow' in response)
260 261
        try:
261 262
            error = json.loads(response.content)
262 263
        except ValueError:
263 264
            self.assertTrue(False)
264
        self.assertEqual(error['badRequest']['message'], 'Method not allowed')
265
        self.assertEqual(error['notAllowed']['message'], 'Method not allowed')
265 266

  
266 267

  
267 268
# Imitate unittest assertions new in Python 2.7
b/snf-pithos-app/pithos/api/functions.py
98 98
                return authenticate(request)
99 99
        return account_list(request)
100 100
    else:
101
        return api.api_method_not_allowed(request)
101
        return api.api_method_not_allowed(request, allowed_methods=['GET'])
102 102

  
103 103

  
104 104
@csrf_exempt
......
117 117
    elif request.method == 'GET':
118 118
        return container_list(request, v_account)
119 119
    else:
120
        return api.api_method_not_allowed(request)
120
        return api.api_method_not_allowed(request,
121
                                          allowed_methods=['HEAD',
122
                                                           'POST',
123
                                                           'GET'])
121 124

  
122 125

  
123 126
@csrf_exempt
......
140 143
    elif request.method == 'GET':
141 144
        return object_list(request, v_account, v_container)
142 145
    else:
143
        return api.api_method_not_allowed(request)
146
        return api.api_method_not_allowed(request,
147
                                          allowed_methods=['HEAD',
148
                                                           'PUT',
149
                                                           'POST',
150
                                                           'DELETE',
151
                                                           'GET'])
144 152

  
145 153

  
146 154
@csrf_exempt
......
172 180
    elif request.method == 'DELETE':
173 181
        return object_delete(request, v_account, v_container, v_object)
174 182
    else:
175
        return api.api_method_not_allowed(request)
183
        return api.api_method_not_allowed(request, allowed_methods=['HEAD',
184
                                                                    'GET',
185
                                                                    'PUT',
186
                                                                    'COPY',
187
                                                                    'MOVE',
188
                                                                    'POST',
189
                                                                    'DELETE'])
176 190

  
177 191

  
178 192
@api_method('GET', token_required=False, user_required=False, logger=logger)
b/snf-pithos-app/pithos/api/test/top_level.py
42 42
    def test_not_allowed_method(self):
43 43
        url = join_urls(self.pithos_path, '/')
44 44
        r = self.head(url)
45
        self.assertEqual(r.status_code, 400)
45
        self.assertEqual(r.status_code, 405)
46
        self.assertTrue('Allow' in r)
47
        self.assertEqual(r['Allow'], 'GET')
46 48
        r = self.put(url, data='')
47
        self.assertEqual(r.status_code, 400)
49
        self.assertEqual(r.status_code, 405)
50
        self.assertTrue('Allow' in r)
51
        self.assertEqual(r['Allow'], 'GET')
48 52
        r = self.post(url, data='')
49
        self.assertEqual(r.status_code, 400)
53
        self.assertEqual(r.status_code, 405)
54
        self.assertTrue('Allow' in r)
55
        self.assertEqual(r['Allow'], 'GET')
50 56
        r = self.delete(url)
51
        self.assertEqual(r.status_code, 400)
57
        self.assertEqual(r.status_code, 405)
58
        self.assertTrue('Allow' in r)
59
        self.assertEqual(r['Allow'], 'GET')
60

  
52 61

  
53 62
    def test_authenticate(self):
54 63
        url = join_urls(self.pithos_path, '/')
b/snf-pithos-app/pithos/api/test/views.py
92 92
                                  get_random_name())
93 93

  
94 94
        r = self.head(self.view_url)
95
        self.assertEqual(r.status_code, 400)
95
        self.assertEqual(r.status_code, 405)
96
        self.assertTrue('Allow' in r)
97
        self.assertEqual(r['Allow'],  'GET')
96 98

  
97 99
        r = self.delete(self.view_url)
98
        self.assertEqual(r.status_code, 400)
100
        self.assertEqual(r.status_code, 405)
101
        self.assertTrue('Allow' in r)
102
        self.assertEqual(r['Allow'],  'GET')
99 103

  
100 104
        r = self.post(self.view_url)
101
        self.assertEqual(r.status_code, 400)
105
        self.assertEqual(r.status_code, 405)
106
        self.assertTrue('Allow' in r)
107
        self.assertEqual(r['Allow'],  'GET')
102 108

  
103 109
        r = self.put(self.view_url)
104
        self.assertEqual(r.status_code, 400)
110
        self.assertEqual(r.status_code, 405)
111
        self.assertTrue('Allow' in r)
112
        self.assertEqual(r['Allow'],  'GET')
105 113

  
106 114
        r = self.copy(self.view_url)
107
        self.assertEqual(r.status_code, 400)
115
        self.assertEqual(r.status_code, 405)
116
        self.assertTrue('Allow' in r)
117
        self.assertEqual(r['Allow'],  'GET')
108 118

  
109 119
        r = self.move(self.view_url)
110
        self.assertEqual(r.status_code, 400)
120
        self.assertEqual(r.status_code, 405)
121
        self.assertTrue('Allow' in r)
122
        self.assertEqual(r['Allow'],  'GET')
111 123

  
112 124

  
113 125
class ObjectGetView(PithosAPITest):
b/snf-pithos-app/pithos/api/urls.py
66 66
pithos_view_patterns = patterns(
67 67
    'pithos.api.views',
68 68
    (r'^view/(?P<v_account>.+?)/(?P<v_container>.+?)/(?P<v_object>.+?)$',
69
     'object_read'))
69
     'object_demux'))
70 70

  
71 71
pithos_patterns = patterns(
72 72
    '',
b/snf-pithos-app/pithos/api/views.py
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
from django.views.decorators.csrf import csrf_exempt
35

  
36
from snf_django.lib import api
37

  
34 38
from pithos.api.functions import _object_read
35 39
from pithos.api.util import api_method, view_method
36 40

  
......
38 42
logger = logging.getLogger(__name__)
39 43

  
40 44

  
45
@csrf_exempt
46
def object_demux(request, v_account, v_container, v_object):
47
    if request.method == 'GET':
48
        return object_read(request, v_account, v_container, v_object)
49
    else:
50
        return api.api_method_not_allowed(request, allowed_methods=['GET'])
51

  
52

  
41 53
@view_method()
42 54
@api_method('GET', format_allowed=True, user_required=True, logger=logger)
43 55
def object_read(request, v_account, v_container, v_object):

Also available in: Unified diff