Skip to content

Commit

Permalink
Merge pull request #273 from mozilla-services/fix_options_permissions
Browse files Browse the repository at this point in the history
When using set_default_permissions OPTIONS calls for CORS does not work anymore.
  • Loading branch information
Natim committed Feb 24, 2015
2 parents 448a9c5 + e571be6 commit ff43402
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 10 deletions.
3 changes: 2 additions & 1 deletion cornice/pyramidhook.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ def register_service_views(config, service):
# before doing anything else, register a view for the OPTIONS method
# if we need to
if service.cors_enabled and 'OPTIONS' not in service.defined_methods:
service.add_view('options', view=get_cors_preflight_view(service))
service.add_view('options', view=get_cors_preflight_view(service),
permission=NO_PERMISSION_REQUIRED)

# register the fallback view, which takes care of returning good error
# messages to the user-agent
Expand Down
6 changes: 3 additions & 3 deletions cornice/tests/ext/test_spore.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,23 @@ def post_coffees(request):
'path': '/coffee',
'method': 'GET',
'formats': ['json'],
})
})

self.assertIn('post_coffees', methods)
self.assertDictEqual(methods['post_coffees'], {
'path': '/coffee',
'method': 'POST',
'formats': ['json'],
'description': post_coffees.__doc__
})
})

self.assertIn('get_coffee', methods)
self.assertDictEqual(methods['get_coffee'], {
'path': '/coffee/:bar/:id',
'method': 'GET',
'formats': ['json'],
'required_params': ['bar', 'id']
})
})

def test_rxjson_spore(self):
rx = Rx.Factory({'register_core_types': True})
Expand Down
47 changes: 41 additions & 6 deletions cornice/tests/test_cors.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
from pyramid import testing
from pyramid.authentication import BasicAuthAuthenticationPolicy
from pyramid.exceptions import NotFound, HTTPBadRequest
from pyramid.interfaces import IAuthorizationPolicy
from pyramid.response import Response
from pyramid.view import view_config
from zope.interface import implementer

from webtest import TestApp

Expand Down Expand Up @@ -59,7 +62,7 @@ def gimme_some_spam_please(request):
return 'spam'


@spam.post()
@spam.post(permission='read-only')
def moar_spam(request):
return 'moar spam'

Expand Down Expand Up @@ -96,14 +99,13 @@ class TestCORS(TestCase):

def setUp(self):
self.config = testing.setUp()
self.config.include("cornice")
self.config.include('cornice')
self.config.add_route('noservice', '/noservice')

self.config.scan("cornice.tests.test_cors")
self.config.scan('cornice.tests.test_cors')
self.app = TestApp(CatchErrors(self.config.make_wsgi_app()))

def tearDown(self):
testing.tearDown()
def tearDown(self):
testing.tearDown()

def test_preflight_cors_klass_post(self):
resp = self.app.options('/cors_klass',
Expand Down Expand Up @@ -312,3 +314,36 @@ def test_existing_non_service_route(self):
resp = self.app.get('/noservice', status=200,
headers={'Origin': 'notmyidea.org'})
self.assertEqual(resp.body, b'No Service here.')


class TestAuthenticatedCORS(TestCase):
def setUp(self):

def check_cred(username, *args, **kwargs):
return [username]

@implementer(IAuthorizationPolicy)
class AuthorizationPolicy(object):
def permits(self, context, principals, permission):
return permission in principals

self.config = testing.setUp()
self.config.include('cornice')
self.config.add_route('noservice', '/noservice')
self.config.set_authorization_policy(AuthorizationPolicy())
self.config.set_authentication_policy(BasicAuthAuthenticationPolicy(
check_cred))
self.config.set_default_permission('readwrite')
self.config.scan('cornice.tests.test_cors')
self.app = TestApp(CatchErrors(self.config.make_wsgi_app()))

def tearDown(self):
testing.tearDown()

def test_post_on_spam_should_be_forbidden(self):
self.app.post('/spam', status=403)

def test_preflight_does_not_need_authentication(self):
self.app.options('/spam', status=200,
headers={'Origin': 'notmyidea.org',
'Access-Control-Request-Method': 'POST'})

0 comments on commit ff43402

Please sign in to comment.