##// END OF EJS Templates
tests: added some more artifact access tests.
marcink -
r4008:786403b1 default
parent child Browse files
Show More
@@ -21,7 +21,8 b' import os'
21 import pytest
21 import pytest
22
22
23 from rhodecode.lib.ext_json import json
23 from rhodecode.lib.ext_json import json
24 from rhodecode.model.db import Session, FileStore
24 from rhodecode.model.auth_token import AuthTokenModel
25 from rhodecode.model.db import Session, FileStore, Repository, User
25 from rhodecode.tests import TestController
26 from rhodecode.tests import TestController
26 from rhodecode.apps.file_store import utils, config_keys
27 from rhodecode.apps.file_store import utils, config_keys
27
28
@@ -32,6 +33,7 b' def route_path(name, params=None, **kwar'
32 base_url = {
33 base_url = {
33 'upload_file': '/_file_store/upload',
34 'upload_file': '/_file_store/upload',
34 'download_file': '/_file_store/download/{fid}',
35 'download_file': '/_file_store/download/{fid}',
36 'download_file_by_token': '/_file_store/token-download/{_auth_token}/{fid}'
35
37
36 }[name].format(**kwargs)
38 }[name].format(**kwargs)
37
39
@@ -124,3 +126,136 b' class TestFileStoreViews(TestController)'
124 status=200)
126 status=200)
125
127
126 assert response.json['store_fid']
128 assert response.json['store_fid']
129
130 @pytest.fixture()
131 def create_artifact_factory(self, tmpdir):
132 def factory(user_id, content):
133 store_path = self.app._pyramid_settings[config_keys.store_path]
134 store = utils.get_file_storage({config_keys.store_path: store_path})
135 fid = 'example.txt'
136
137 filesystem_file = os.path.join(str(tmpdir), fid)
138 with open(filesystem_file, 'wb') as f:
139 f.write(content)
140
141 with open(filesystem_file, 'rb') as f:
142 store_uid, metadata = store.save_file(f, fid, extra_metadata={'filename': fid})
143
144 entry = FileStore.create(
145 file_uid=store_uid, filename=metadata["filename"],
146 file_hash=metadata["sha256"], file_size=metadata["size"],
147 file_display_name='file_display_name',
148 file_description='repo artifact `{}`'.format(metadata["filename"]),
149 check_acl=True, user_id=user_id,
150 )
151 Session().add(entry)
152 Session().commit()
153 return entry
154 return factory
155
156 def test_download_file_non_scoped(self, user_util, create_artifact_factory):
157 user = self.log_user()
158 user_id = user['user_id']
159 content = 'HELLO MY NAME IS ARTIFACT !'
160
161 artifact = create_artifact_factory(user_id, content)
162 file_uid = artifact.file_uid
163 response = self.app.get(route_path('download_file', fid=file_uid), status=200)
164 assert response.text == content
165
166 # log-in to new user and test download again
167 user = user_util.create_user(password='qweqwe')
168 self.log_user(user.username, 'qweqwe')
169 response = self.app.get(route_path('download_file', fid=file_uid), status=200)
170 assert response.text == content
171
172 def test_download_file_scoped_to_repo(self, user_util, create_artifact_factory):
173 user = self.log_user()
174 user_id = user['user_id']
175 content = 'HELLO MY NAME IS ARTIFACT !'
176
177 artifact = create_artifact_factory(user_id, content)
178 # bind to repo
179 repo = user_util.create_repo()
180 repo_id = repo.repo_id
181 artifact.scope_repo_id = repo_id
182 Session().add(artifact)
183 Session().commit()
184
185 file_uid = artifact.file_uid
186 response = self.app.get(route_path('download_file', fid=file_uid), status=200)
187 assert response.text == content
188
189 # log-in to new user and test download again
190 user = user_util.create_user(password='qweqwe')
191 self.log_user(user.username, 'qweqwe')
192 response = self.app.get(route_path('download_file', fid=file_uid), status=200)
193 assert response.text == content
194
195 # forbid user the rights to repo
196 repo = Repository.get(repo_id)
197 user_util.grant_user_permission_to_repo(repo, user, 'repository.none')
198 self.app.get(route_path('download_file', fid=file_uid), status=404)
199
200 def test_download_file_scoped_to_user(self, user_util, create_artifact_factory):
201 user = self.log_user()
202 user_id = user['user_id']
203 content = 'HELLO MY NAME IS ARTIFACT !'
204
205 artifact = create_artifact_factory(user_id, content)
206 # bind to user
207 user = user_util.create_user(password='qweqwe')
208
209 artifact.scope_user_id = user.user_id
210 Session().add(artifact)
211 Session().commit()
212
213 # artifact creator doesn't have access since it's bind to another user
214 file_uid = artifact.file_uid
215 self.app.get(route_path('download_file', fid=file_uid), status=404)
216
217 # log-in to new user and test download again, should be ok since we're bind to this artifact
218 self.log_user(user.username, 'qweqwe')
219 response = self.app.get(route_path('download_file', fid=file_uid), status=200)
220 assert response.text == content
221
222 def test_download_file_scoped_to_repo_with_bad_token(self, user_util, create_artifact_factory):
223 user_id = User.get_first_super_admin().user_id
224 content = 'HELLO MY NAME IS ARTIFACT !'
225
226 artifact = create_artifact_factory(user_id, content)
227 # bind to repo
228 repo = user_util.create_repo()
229 repo_id = repo.repo_id
230 artifact.scope_repo_id = repo_id
231 Session().add(artifact)
232 Session().commit()
233
234 file_uid = artifact.file_uid
235 self.app.get(route_path('download_file_by_token',
236 _auth_token='bogus', fid=file_uid), status=302)
237
238 def test_download_file_scoped_to_repo_with_token(self, user_util, create_artifact_factory):
239 user = User.get_first_super_admin()
240 AuthTokenModel().create(user, 'test artifact token',
241 role=AuthTokenModel.cls.ROLE_ARTIFACT_DOWNLOAD)
242
243 user = User.get_first_super_admin()
244 artifact_token = user.artifact_token
245
246 user_id = User.get_first_super_admin().user_id
247 content = 'HELLO MY NAME IS ARTIFACT !'
248
249 artifact = create_artifact_factory(user_id, content)
250 # bind to repo
251 repo = user_util.create_repo()
252 repo_id = repo.repo_id
253 artifact.scope_repo_id = repo_id
254 Session().add(artifact)
255 Session().commit()
256
257 file_uid = artifact.file_uid
258 response = self.app.get(
259 route_path('download_file_by_token',
260 _auth_token=artifact_token, fid=file_uid), status=200)
261 assert response.text == content
@@ -87,7 +87,7 b' class FileStoreView(BaseAppView):'
87 entry = FileStore.create(
87 entry = FileStore.create(
88 file_uid=store_uid, filename=metadata["filename"],
88 file_uid=store_uid, filename=metadata["filename"],
89 file_hash=metadata["sha256"], file_size=metadata["size"],
89 file_hash=metadata["sha256"], file_size=metadata["size"],
90 file_description='upload attachment',
90 file_description=u'upload attachment',
91 check_acl=False, user_id=self._rhodecode_user.user_id
91 check_acl=False, user_id=self._rhodecode_user.user_id
92 )
92 )
93 Session().add(entry)
93 Session().add(entry)
@@ -116,6 +116,8 b' class FileStoreView(BaseAppView):'
116
116
117 # private upload for user
117 # private upload for user
118 if db_obj.check_acl and db_obj.scope_user_id:
118 if db_obj.check_acl and db_obj.scope_user_id:
119 log.debug('Artifact: checking scope access for bound artifact user: `%s`',
120 db_obj.scope_user_id)
119 user = db_obj.user
121 user = db_obj.user
120 if self._rhodecode_db_user.user_id != user.user_id:
122 if self._rhodecode_db_user.user_id != user.user_id:
121 log.warning('Access to file store object forbidden')
123 log.warning('Access to file store object forbidden')
@@ -123,6 +125,8 b' class FileStoreView(BaseAppView):'
123
125
124 # scoped to repository permissions
126 # scoped to repository permissions
125 if db_obj.check_acl and db_obj.scope_repo_id:
127 if db_obj.check_acl and db_obj.scope_repo_id:
128 log.debug('Artifact: checking scope access for bound artifact repo: `%s`',
129 db_obj.scope_repo_id)
126 repo = db_obj.repo
130 repo = db_obj.repo
127 perm_set = ['repository.read', 'repository.write', 'repository.admin']
131 perm_set = ['repository.read', 'repository.write', 'repository.admin']
128 has_perm = HasRepoPermissionAny(*perm_set)(repo.repo_name, 'FileStore check')
132 has_perm = HasRepoPermissionAny(*perm_set)(repo.repo_name, 'FileStore check')
@@ -132,6 +136,8 b' class FileStoreView(BaseAppView):'
132
136
133 # scoped to repository group permissions
137 # scoped to repository group permissions
134 if db_obj.check_acl and db_obj.scope_repo_group_id:
138 if db_obj.check_acl and db_obj.scope_repo_group_id:
139 log.debug('Artifact: checking scope access for bound artifact repo group: `%s`',
140 db_obj.scope_repo_group_id)
135 repo_group = db_obj.repo_group
141 repo_group = db_obj.repo_group
136 perm_set = ['group.read', 'group.write', 'group.admin']
142 perm_set = ['group.read', 'group.write', 'group.admin']
137 has_perm = HasRepoGroupPermissionAny(*perm_set)(repo_group.group_name, 'FileStore check')
143 has_perm = HasRepoGroupPermissionAny(*perm_set)(repo_group.group_name, 'FileStore check')
@@ -152,7 +158,9 b' class FileStoreView(BaseAppView):'
152 log.debug('Requesting FID:%s from store %s', file_uid, self.storage)
158 log.debug('Requesting FID:%s from store %s', file_uid, self.storage)
153 return self._serve_file(file_uid)
159 return self._serve_file(file_uid)
154
160
161 # in addition to @LoginRequired ACL is checked by scopes
155 @LoginRequired(auth_token_access=[UserApiKeys.ROLE_ARTIFACT_DOWNLOAD])
162 @LoginRequired(auth_token_access=[UserApiKeys.ROLE_ARTIFACT_DOWNLOAD])
163 @NotAnonymous()
156 @view_config(route_name='download_file_by_token')
164 @view_config(route_name='download_file_by_token')
157 def download_file_by_token(self):
165 def download_file_by_token(self):
158 """
166 """
General Comments 0
You need to be logged in to leave comments. Login now