diff --git a/rhodecode/apps/file_store/backends/__init__.py b/rhodecode/apps/file_store/backends/__init__.py new file mode 100644 --- /dev/null +++ b/rhodecode/apps/file_store/backends/__init__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2016-2019 RhodeCode GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License, version 3 +# (only), as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# This program is dual-licensed. If you wish to learn more about the +# RhodeCode Enterprise Edition, including its added features, Support services, +# and proprietary license terms, please see https://rhodecode.com/licenses/ diff --git a/rhodecode/apps/file_store/local_store.py b/rhodecode/apps/file_store/backends/local_store.py rename from rhodecode/apps/file_store/local_store.py rename to rhodecode/apps/file_store/backends/local_store.py diff --git a/rhodecode/apps/file_store/utils.py b/rhodecode/apps/file_store/utils.py --- a/rhodecode/apps/file_store/utils.py +++ b/rhodecode/apps/file_store/utils.py @@ -25,7 +25,7 @@ import pathlib2 def get_file_storage(settings): - from rhodecode.apps.file_store.local_store import LocalFileStorage + from rhodecode.apps.file_store.backends.local_store import LocalFileStorage from rhodecode.apps.file_store import config_keys store_path = settings.get(config_keys.store_path) return LocalFileStorage(base_path=store_path) diff --git a/rhodecode/apps/file_store/views.py b/rhodecode/apps/file_store/views.py --- a/rhodecode/apps/file_store/views.py +++ b/rhodecode/apps/file_store/views.py @@ -46,6 +46,54 @@ class FileStoreView(BaseAppView): self.storage = utils.get_file_storage(self.request.registry.settings) return c + def _serve_file(self, file_uid): + + if not self.storage.exists(file_uid): + store_path = self.storage.store_path(file_uid) + log.debug('File with FID:%s not found in the store under `%s`', + file_uid, store_path) + raise HTTPNotFound() + + db_obj = FileStore().query().filter(FileStore.file_uid == file_uid).scalar() + if not db_obj: + raise HTTPNotFound() + + # private upload for user + if db_obj.check_acl and db_obj.scope_user_id: + log.debug('Artifact: checking scope access for bound artifact user: `%s`', + db_obj.scope_user_id) + user = db_obj.user + if self._rhodecode_db_user.user_id != user.user_id: + log.warning('Access to file store object forbidden') + raise HTTPNotFound() + + # scoped to repository permissions + if db_obj.check_acl and db_obj.scope_repo_id: + log.debug('Artifact: checking scope access for bound artifact repo: `%s`', + db_obj.scope_repo_id) + repo = db_obj.repo + perm_set = ['repository.read', 'repository.write', 'repository.admin'] + has_perm = HasRepoPermissionAny(*perm_set)(repo.repo_name, 'FileStore check') + if not has_perm: + log.warning('Access to file store object `%s` forbidden', file_uid) + raise HTTPNotFound() + + # scoped to repository group permissions + if db_obj.check_acl and db_obj.scope_repo_group_id: + log.debug('Artifact: checking scope access for bound artifact repo group: `%s`', + db_obj.scope_repo_group_id) + repo_group = db_obj.repo_group + perm_set = ['group.read', 'group.write', 'group.admin'] + has_perm = HasRepoGroupPermissionAny(*perm_set)(repo_group.group_name, 'FileStore check') + if not has_perm: + log.warning('Access to file store object `%s` forbidden', file_uid) + raise HTTPNotFound() + + FileStore.bump_access_counter(file_uid) + + file_path = self.storage.store_path(file_uid) + return FileResponse(file_path) + @LoginRequired() @NotAnonymous() @CSRFRequired() @@ -102,54 +150,6 @@ class FileStoreView(BaseAppView): return {'store_fid': store_uid, 'access_path': h.route_path('download_file', fid=store_uid)} - def _serve_file(self, file_uid): - - if not self.storage.exists(file_uid): - store_path = self.storage.store_path(file_uid) - log.debug('File with FID:%s not found in the store under `%s`', - file_uid, store_path) - raise HTTPNotFound() - - db_obj = FileStore().query().filter(FileStore.file_uid == file_uid).scalar() - if not db_obj: - raise HTTPNotFound() - - # private upload for user - if db_obj.check_acl and db_obj.scope_user_id: - log.debug('Artifact: checking scope access for bound artifact user: `%s`', - db_obj.scope_user_id) - user = db_obj.user - if self._rhodecode_db_user.user_id != user.user_id: - log.warning('Access to file store object forbidden') - raise HTTPNotFound() - - # scoped to repository permissions - if db_obj.check_acl and db_obj.scope_repo_id: - log.debug('Artifact: checking scope access for bound artifact repo: `%s`', - db_obj.scope_repo_id) - repo = db_obj.repo - perm_set = ['repository.read', 'repository.write', 'repository.admin'] - has_perm = HasRepoPermissionAny(*perm_set)(repo.repo_name, 'FileStore check') - if not has_perm: - log.warning('Access to file store object `%s` forbidden', file_uid) - raise HTTPNotFound() - - # scoped to repository group permissions - if db_obj.check_acl and db_obj.scope_repo_group_id: - log.debug('Artifact: checking scope access for bound artifact repo group: `%s`', - db_obj.scope_repo_group_id) - repo_group = db_obj.repo_group - perm_set = ['group.read', 'group.write', 'group.admin'] - has_perm = HasRepoGroupPermissionAny(*perm_set)(repo_group.group_name, 'FileStore check') - if not has_perm: - log.warning('Access to file store object `%s` forbidden', file_uid) - raise HTTPNotFound() - - FileStore.bump_access_counter(file_uid) - - file_path = self.storage.store_path(file_uid) - return FileResponse(file_path) - # ACL is checked by scopes, if no scope the file is accessible to all @view_config(route_name='download_file') def download_file(self):