Revision 2aba7764

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

  
273 273

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

  
321 321

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

  
490 490

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

  
574 574

  
575 575
def make_membership_query(input_data):
b/snf-astakos-app/astakos/api/quotas.py
96 96
        return get_pending_commissions(request)
97 97
    elif method == 'POST':
98 98
        return issue_commission(request)
99
    return api.api_method_not_allowed(request)
99
    return api.api_method_not_allowed(request, allowed_methods=['GET', 'POST'])
100 100

  
101 101

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

  
402 402
        # Bad Request
403 403
        r = client.head(u('commissions'))
404
        self.assertEqual(r.status_code, 400)
404
        self.assertEqual(r.status_code, 405)
405
        self.assertTrue('Allow' in r)
405 406

  
406 407

  
407 408
class TokensApiTest(TestCase):
......
451 452

  
452 453
        # Check not allowed method
453 454
        r = client.get(url, post_data={})
454
        self.assertEqual(r.status_code, 400)
455
        self.assertEqual(r.status_code, 405)
456
        self.assertTrue('Allow' in r)
457
        self.assertEqual(r['Allow'], 'POST')
455 458

  
456 459
        # check public mode
457 460
        r = client.post(url, CONTENT_LENGTH=0)
b/snf-astakos-app/astakos/im/tests/projects.py
487 487

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

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

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

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

  
502 506
        status = self.project_action(1, "nonex", h_owner)
503 507
        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
71 71
    elif request.method == 'POST':
72 72
        return allocate_floating_ip(request)
73 73
    else:
74
        return api.api_method_not_allowed(request)
74
        return api.api_method_not_allowed(request,
75
                                          allowed_methods=['GET', 'POST'])
75 76

  
76 77

  
77 78
def floating_ip_demux(request, floating_ip_id):
......
82 83
    elif request.method == 'PUT':
83 84
        return update_floating_ip(request, floating_ip_id)
84 85
    else:
85
        return api.api_method_not_allowed(request)
86
        return api.api_method_not_allowed(request,
87
                                          allowed_methods=['GET', 'DELETE'])
86 88

  
87 89

  
88 90
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
62 62
    elif request.method == 'POST':
63 63
        return create_network(request)
64 64
    else:
65
        return api.api_method_not_allowed(request)
65
        return api.api_method_not_allowed(request,
66
                                          allowed_methods=['GET', 'POST'])
66 67

  
67 68

  
68 69
def network_demux(request, network_id):
......
74 75
    elif request.method == 'PUT':
75 76
        return update_network(request, network_id)
76 77
    else:
77
        return api.api_method_not_allowed(request)
78
        return api.api_method_not_allowed(request,
79
                                          allowed_methods=['GET',
80
                                                           'PUT',
81
                                                           'DELETE'])
78 82

  
79 83

  
80 84
@api.api_method(http_method='GET', user_required=True, logger=log)
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_attachments(nic):
b/snf-django-lib/snf_django/lib/api/__init__.py
91 91

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

  
96 97
                # Get authentication token
97 98
                request.x_auth_token = None
......
246 247
        data = json.dumps(d)
247 248

  
248 249
    response = HttpResponse(data, status=fault.code)
250
    if response.status_code == 405 and hasattr(fault, 'allowed_methods'):
251
        response['Allow'] = ','.join(fault.allowed_methods)
249 252
    update_response_headers(request, response)
250 253
    return response
251 254

  
......
256 259

  
257 260

  
258 261
@api_method(token_required=False, user_required=False)
259
def api_method_not_allowed(request):
260
    raise faults.BadRequest('Method not allowed')
262
def api_method_not_allowed(request, allowed_methods):
263
    raise faults.NotAllowed("Method not allowed",
264
                            allowed_methods=allowed_methods)
261 265

  
262 266

  
263 267
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
268 268
        self.assertFault(response, 409, "conflict")
269 269

  
270 270
    def assertMethodNotAllowed(self, response):
271
        self.assertFault(response, 400, 'badRequest')
271
        self.assertFault(response, 405, 'notAllowed')
272
        self.assertTrue('Allow' in response)
272 273
        try:
273 274
            error = json.loads(response.content)
274 275
        except ValueError:
275 276
            self.assertTrue(False)
276
        self.assertEqual(error['badRequest']['message'], 'Method not allowed')
277
        self.assertEqual(error['notAllowed']['message'], 'Method not allowed')
277 278

  
278 279

  
279 280
# 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