diff --git a/development.ini b/development.ini --- a/development.ini +++ b/development.ini @@ -153,18 +153,6 @@ show_revision_number = false ## Kallithea url, ie. http[s]://kallithea.example.com/_admin/gists/ gist_alias_url = -## white list of API enabled controllers. This allows to add list of -## controllers to which access will be enabled by api_key. eg: to enable -## api access to raw_files put `FilesController:raw`, to enable access to patches -## add `ChangesetController:changeset_patch`. This list should be "," separated -## Syntax is :. Check debug logs for generated names -## Recommended settings below are commented out: -api_access_controllers_whitelist = -# ChangesetController:changeset_patch, -# ChangesetController:changeset_raw, -# FilesController:raw, -# FilesController:archivefile - ## default encoding used to convert from and to unicode ## can be also a comma separated list of encoding in case of mixed encodings default_encoding = utf-8 diff --git a/docs/api/api.rst b/docs/api/api.rst --- a/docs/api/api.rst +++ b/docs/api/api.rst @@ -1238,24 +1238,8 @@ OUTPUT:: API access for web views ------------------------ -API access can also be turned on for each web view in Kallithea that is -decorated with the ``@LoginRequired`` decorator. Some views use -``@LoginRequired(api_access=True)`` and are always available. By default only -RSS/Atom feed views are enabled. Other views are -only available if they have been whitelisted. Edit the -``api_access_controllers_whitelist`` option in your .ini file and define views -that should have API access enabled. - -For example, to enable API access to patch/diff, raw file and archive:: - - api_access_controllers_whitelist = - ChangesetController:changeset_patch, - ChangesetController:changeset_raw, - FilesController:raw, - FilesController:archivefile - -After this change, a Kallithea view can be accessed without login using -bearer authentication, by including this header with the request:: +Kallithea HTTP entry points can also be accessed without login using bearer +authentication by including this header with the request:: Authentication: Bearer diff --git a/kallithea/controllers/feed.py b/kallithea/controllers/feed.py --- a/kallithea/controllers/feed.py +++ b/kallithea/controllers/feed.py @@ -51,7 +51,7 @@ ttl = "5" class FeedController(BaseRepoController): - @LoginRequired(api_access=True, allow_default_user=True) + @LoginRequired(allow_default_user=True) @HasRepoPermissionLevelDecorator('read') def _before(self, *args, **kwargs): super(FeedController, self)._before(*args, **kwargs) diff --git a/kallithea/controllers/journal.py b/kallithea/controllers/journal.py --- a/kallithea/controllers/journal.py +++ b/kallithea/controllers/journal.py @@ -220,7 +220,7 @@ class JournalController(BaseController): return render('journal/journal.html') - @LoginRequired(api_access=True) + @LoginRequired() def journal_atom(self): """ Produce an atom-1.0 feed via feedgenerator module @@ -231,7 +231,7 @@ class JournalController(BaseController): .all() return self._atom_feed(following, public=False) - @LoginRequired(api_access=True) + @LoginRequired() def journal_rss(self): """ Produce an rss feed via feedgenerator module @@ -289,7 +289,7 @@ class JournalController(BaseController): return render('journal/public_journal.html') - @LoginRequired(api_access=True, allow_default_user=True) + @LoginRequired(allow_default_user=True) def public_journal_atom(self): """ Produce an atom-1.0 feed via feedgenerator module @@ -301,7 +301,7 @@ class JournalController(BaseController): return self._atom_feed(c.following) - @LoginRequired(api_access=True, allow_default_user=True) + @LoginRequired(allow_default_user=True) def public_journal_rss(self): """ Produce an rss2 feed via feedgenerator module diff --git a/kallithea/lib/auth.py b/kallithea/lib/auth.py --- a/kallithea/lib/auth.py +++ b/kallithea/lib/auth.py @@ -367,28 +367,6 @@ def _cached_perms_data(user_id, user_is_ return permissions -def allowed_api_access(controller_name, whitelist=None, api_key=None): - """ - Check if given controller_name is in whitelist API access - """ - if not whitelist: - from kallithea import CONFIG - whitelist = aslist(CONFIG.get('api_access_controllers_whitelist'), - sep=',') - log.debug('whitelist of API access is: %s', whitelist) - api_access_valid = controller_name in whitelist - if api_access_valid: - log.debug('controller:%s is in API whitelist', controller_name) - else: - msg = 'controller: %s is *NOT* in API whitelist' % (controller_name) - if api_key: - # if we use API key and don't have access it's a warning - log.warning(msg) - else: - log.debug(msg) - return api_access_valid - - class AuthUser(object): """ Represents a Kallithea user, including various authentication and @@ -689,13 +667,10 @@ class LoginRequired(object): If the "default" user is enabled and allow_default_user is true, that is considered valid too. - Also checks that IP address is allowed, and if using API key instead - of regular cookie authentication, checks that API key access is allowed - (based on `api_access` parameter and the API view whitelist). + Also checks that IP address is allowed. """ - def __init__(self, api_access=False, allow_default_user=False): - self.api_access = api_access + def __init__(self, allow_default_user=False): self.allow_default_user = allow_default_user def __call__(self, func): @@ -708,16 +683,9 @@ class LoginRequired(object): log.debug('Checking access for user %s @ %s', user, loc) # Check if we used an API key to authenticate. - api_key = user.authenticating_api_key - if api_key is not None: - # Check that controller is enabled for API key usage. - if not self.api_access and not allowed_api_access(loc, api_key=api_key): - # controller does not allow API access - log.warning('API access to %s is not allowed', loc) - raise HTTPForbidden() - + if user.authenticating_api_key is not None: log.info('user %s authenticated with API key ****%s @ %s', - user, api_key[-4:], loc) + user, user.authenticating_api_key[-4:], loc) return func(*fargs, **fkwargs) # CSRF protection: Whenever a request has ambient authority (whether diff --git a/kallithea/lib/paster_commands/template.ini.mako b/kallithea/lib/paster_commands/template.ini.mako --- a/kallithea/lib/paster_commands/template.ini.mako +++ b/kallithea/lib/paster_commands/template.ini.mako @@ -250,18 +250,6 @@ show_revision_number = false <%text>## Kallithea url, ie. http[s]://kallithea.example.com/_admin/gists/ gist_alias_url = -<%text>## white list of API enabled controllers. This allows to add list of -<%text>## controllers to which access will be enabled by api_key. eg: to enable -<%text>## api access to raw_files put `FilesController:raw`, to enable access to patches -<%text>## add `ChangesetController:changeset_patch`. This list should be "," separated -<%text>## Syntax is :. Check debug logs for generated names -<%text>## Recommended settings below are commented out: -api_access_controllers_whitelist = -# ChangesetController:changeset_patch, -# ChangesetController:changeset_raw, -# FilesController:raw, -# FilesController:archivefile - <%text>## default encoding used to convert from and to unicode <%text>## can be also a comma separated list of encoding in case of mixed encodings default_encoding = utf-8 diff --git a/kallithea/tests/functional/test_login.py b/kallithea/tests/functional/test_login.py --- a/kallithea/tests/functional/test_login.py +++ b/kallithea/tests/functional/test_login.py @@ -441,10 +441,6 @@ class TestLoginController(TestController # API #========================================================================== - def _get_api_whitelist(self, values=None): - config = {'api_access_controllers_whitelist': values or []} - return config - def _api_key_test(self, api_key, status): """Verifies HTTP status code for accessing an auth-requiring page, using the given api_key URL parameter as well as using the API key @@ -476,45 +472,22 @@ class TestLoginController(TestController ('none', None, 302), ('empty_string', '', 403), ('fake_number', '123456', 403), - ('proper_api_key', True, 403) - ]) - def test_access_not_whitelisted_page_via_api_key(self, test_name, api_key, code): - whitelist = self._get_api_whitelist([]) - with mock.patch('kallithea.CONFIG', whitelist): - assert [] == whitelist['api_access_controllers_whitelist'] - self._api_key_test(api_key, code) - - @parametrize('test_name,api_key,code', [ - ('none', None, 302), - ('empty_string', '', 403), - ('fake_number', '123456', 403), ('fake_not_alnum', 'a-z', 403), ('fake_api_key', '0123456789abcdef0123456789ABCDEF01234567', 403), ('proper_api_key', True, 200) ]) - def test_access_whitelisted_page_via_api_key(self, test_name, api_key, code): - whitelist = self._get_api_whitelist(['ChangesetController:changeset_raw']) - with mock.patch('kallithea.CONFIG', whitelist): - assert ['ChangesetController:changeset_raw'] == whitelist['api_access_controllers_whitelist'] - self._api_key_test(api_key, code) + def test_access_page_via_api_key(self, test_name, api_key, code): + self._api_key_test(api_key, code) def test_access_page_via_extra_api_key(self): - whitelist = self._get_api_whitelist(['ChangesetController:changeset_raw']) - with mock.patch('kallithea.CONFIG', whitelist): - assert ['ChangesetController:changeset_raw'] == whitelist['api_access_controllers_whitelist'] - - new_api_key = ApiKeyModel().create(TEST_USER_ADMIN_LOGIN, u'test') - Session().commit() - self._api_key_test(new_api_key.api_key, status=200) + new_api_key = ApiKeyModel().create(TEST_USER_ADMIN_LOGIN, u'test') + Session().commit() + self._api_key_test(new_api_key.api_key, status=200) def test_access_page_via_expired_api_key(self): - whitelist = self._get_api_whitelist(['ChangesetController:changeset_raw']) - with mock.patch('kallithea.CONFIG', whitelist): - assert ['ChangesetController:changeset_raw'] == whitelist['api_access_controllers_whitelist'] - - new_api_key = ApiKeyModel().create(TEST_USER_ADMIN_LOGIN, u'test') - Session().commit() - # patch the API key and make it expired - new_api_key.expires = 0 - Session().commit() - self._api_key_test(new_api_key.api_key, status=403) + new_api_key = ApiKeyModel().create(TEST_USER_ADMIN_LOGIN, u'test') + Session().commit() + # patch the API key and make it expired + new_api_key.expires = 0 + Session().commit() + self._api_key_test(new_api_key.api_key, status=403)