##// END OF EJS Templates
search-bar: forbid anonymous users to search
marcink -
r2776:5a351218 default
parent child Browse files
Show More
@@ -1,374 +1,376 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2018 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import re
22 22 import logging
23 23 import collections
24 24
25 25 from pyramid.view import view_config
26 26
27 27 from rhodecode.apps._base import BaseAppView
28 28 from rhodecode.lib import helpers as h
29 29 from rhodecode.lib.auth import (
30 30 LoginRequired, NotAnonymous, HasRepoGroupPermissionAnyDecorator)
31 31 from rhodecode.lib.index import searcher_from_config
32 32 from rhodecode.lib.utils2 import safe_unicode, str2bool
33 33 from rhodecode.lib.ext_json import json
34 34 from rhodecode.model.db import (
35 35 func, or_, in_filter_generator, Repository, RepoGroup, User, UserGroup)
36 36 from rhodecode.model.repo import RepoModel
37 37 from rhodecode.model.repo_group import RepoGroupModel
38 38 from rhodecode.model.scm import RepoGroupList, RepoList
39 39 from rhodecode.model.user import UserModel
40 40 from rhodecode.model.user_group import UserGroupModel
41 41
42 42 log = logging.getLogger(__name__)
43 43
44 44
45 45 class HomeView(BaseAppView):
46 46
47 47 def load_default_context(self):
48 48 c = self._get_local_tmpl_context()
49 49 c.user = c.auth_user.get_instance()
50 50
51 51 return c
52 52
53 53 @LoginRequired()
54 54 @view_config(
55 55 route_name='user_autocomplete_data', request_method='GET',
56 56 renderer='json_ext', xhr=True)
57 57 def user_autocomplete_data(self):
58 58 self.load_default_context()
59 59 query = self.request.GET.get('query')
60 60 active = str2bool(self.request.GET.get('active') or True)
61 61 include_groups = str2bool(self.request.GET.get('user_groups'))
62 62 expand_groups = str2bool(self.request.GET.get('user_groups_expand'))
63 63 skip_default_user = str2bool(self.request.GET.get('skip_default_user'))
64 64
65 65 log.debug('generating user list, query:%s, active:%s, with_groups:%s',
66 66 query, active, include_groups)
67 67
68 68 _users = UserModel().get_users(
69 69 name_contains=query, only_active=active)
70 70
71 71 def maybe_skip_default_user(usr):
72 72 if skip_default_user and usr['username'] == UserModel.cls.DEFAULT_USER:
73 73 return False
74 74 return True
75 75 _users = filter(maybe_skip_default_user, _users)
76 76
77 77 if include_groups:
78 78 # extend with user groups
79 79 _user_groups = UserGroupModel().get_user_groups(
80 80 name_contains=query, only_active=active,
81 81 expand_groups=expand_groups)
82 82 _users = _users + _user_groups
83 83
84 84 return {'suggestions': _users}
85 85
86 86 @LoginRequired()
87 87 @NotAnonymous()
88 88 @view_config(
89 89 route_name='user_group_autocomplete_data', request_method='GET',
90 90 renderer='json_ext', xhr=True)
91 91 def user_group_autocomplete_data(self):
92 92 self.load_default_context()
93 93 query = self.request.GET.get('query')
94 94 active = str2bool(self.request.GET.get('active') or True)
95 95 expand_groups = str2bool(self.request.GET.get('user_groups_expand'))
96 96
97 97 log.debug('generating user group list, query:%s, active:%s',
98 98 query, active)
99 99
100 100 _user_groups = UserGroupModel().get_user_groups(
101 101 name_contains=query, only_active=active,
102 102 expand_groups=expand_groups)
103 103 _user_groups = _user_groups
104 104
105 105 return {'suggestions': _user_groups}
106 106
107 107 def _get_repo_list(self, name_contains=None, repo_type=None, limit=20):
108 108 org_query = name_contains
109 109 allowed_ids = self._rhodecode_user.repo_acl_ids(
110 110 ['repository.read', 'repository.write', 'repository.admin'],
111 111 cache=False, name_filter=name_contains) or [-1]
112 112
113 113 query = Repository.query()\
114 114 .order_by(func.length(Repository.repo_name))\
115 115 .order_by(Repository.repo_name)\
116 116 .filter(or_(
117 117 # generate multiple IN to fix limitation problems
118 118 *in_filter_generator(Repository.repo_id, allowed_ids)
119 119 ))
120 120
121 121 if repo_type:
122 122 query = query.filter(Repository.repo_type == repo_type)
123 123
124 124 if name_contains:
125 125 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
126 126 query = query.filter(
127 127 Repository.repo_name.ilike(ilike_expression))
128 128 query = query.limit(limit)
129 129
130 130 acl_iter = query
131 131
132 132 return [
133 133 {
134 134 'id': obj.repo_name,
135 135 'value': org_query,
136 136 'value_display': obj.repo_name,
137 137 'text': obj.repo_name,
138 138 'type': 'repo',
139 139 'repo_id': obj.repo_id,
140 140 'repo_type': obj.repo_type,
141 141 'private': obj.private,
142 142 'url': h.route_path('repo_summary', repo_name=obj.repo_name)
143 143 }
144 144 for obj in acl_iter]
145 145
146 146 def _get_repo_group_list(self, name_contains=None, limit=20):
147 147 org_query = name_contains
148 148 allowed_ids = self._rhodecode_user.repo_group_acl_ids(
149 149 ['group.read', 'group.write', 'group.admin'],
150 150 cache=False, name_filter=name_contains) or [-1]
151 151
152 152 query = RepoGroup.query()\
153 153 .order_by(func.length(RepoGroup.group_name))\
154 154 .order_by(RepoGroup.group_name) \
155 155 .filter(or_(
156 156 # generate multiple IN to fix limitation problems
157 157 *in_filter_generator(RepoGroup.group_id, allowed_ids)
158 158 ))
159 159
160 160 if name_contains:
161 161 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
162 162 query = query.filter(
163 163 RepoGroup.group_name.ilike(ilike_expression))
164 164 query = query.limit(limit)
165 165
166 166 acl_iter = query
167 167
168 168 return [
169 169 {
170 170 'id': obj.group_name,
171 171 'value': org_query,
172 172 'value_display': obj.group_name,
173 173 'type': 'repo_group',
174 174 'url': h.route_path(
175 175 'repo_group_home', repo_group_name=obj.group_name)
176 176 }
177 177 for obj in acl_iter]
178 178
179 179 def _get_user_list(self, name_contains=None, limit=20):
180 180 org_query = name_contains
181 181 if not name_contains:
182 182 return []
183 183
184 184 name_contains = re.compile('(?:user:)(.+)').findall(name_contains)
185 185 if len(name_contains) != 1:
186 186 return []
187 187 name_contains = name_contains[0]
188 188
189 189 query = User.query()\
190 190 .order_by(func.length(User.username))\
191 191 .order_by(User.username) \
192 192 .filter(User.username != User.DEFAULT_USER)
193 193
194 194 if name_contains:
195 195 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
196 196 query = query.filter(
197 197 User.username.ilike(ilike_expression))
198 198 query = query.limit(limit)
199 199
200 200 acl_iter = query
201 201
202 202 return [
203 203 {
204 204 'id': obj.user_id,
205 205 'value': org_query,
206 206 'value_display': obj.username,
207 207 'type': 'user',
208 208 'icon_link': h.gravatar_url(obj.email, 30),
209 209 'url': h.route_path(
210 210 'user_profile', username=obj.username)
211 211 }
212 212 for obj in acl_iter]
213 213
214 214 def _get_hash_commit_list(self, auth_user, query):
215 215 org_query = query
216 216 if not query or len(query) < 3:
217 217 return []
218 218
219 219 commit_hashes = re.compile('(?:commit:)([0-9a-f]{2,40})').findall(query)
220 220
221 221 if len(commit_hashes) != 1:
222 222 return []
223 223 commit_hash = commit_hashes[0]
224 224
225 225 searcher = searcher_from_config(self.request.registry.settings)
226 226 result = searcher.search(
227 227 'commit_id:%s*' % commit_hash, 'commit', auth_user,
228 228 raise_on_exc=False)
229 229
230 230 return [
231 231 {
232 232 'id': entry['commit_id'],
233 233 'value': org_query,
234 234 'value_display': 'repo `{}` commit: {}'.format(
235 235 entry['repository'], entry['commit_id']),
236 236 'type': 'commit',
237 237 'repo': entry['repository'],
238 238 'url': h.route_path(
239 239 'repo_commit',
240 240 repo_name=entry['repository'], commit_id=entry['commit_id'])
241 241 }
242 242 for entry in result['results']]
243 243
244 244 @LoginRequired()
245 245 @view_config(
246 246 route_name='repo_list_data', request_method='GET',
247 247 renderer='json_ext', xhr=True)
248 248 def repo_list_data(self):
249 249 _ = self.request.translate
250 250 self.load_default_context()
251 251
252 252 query = self.request.GET.get('query')
253 253 repo_type = self.request.GET.get('repo_type')
254 254 log.debug('generating repo list, query:%s, repo_type:%s',
255 255 query, repo_type)
256 256
257 257 res = []
258 258 repos = self._get_repo_list(query, repo_type=repo_type)
259 259 if repos:
260 260 res.append({
261 261 'text': _('Repositories'),
262 262 'children': repos
263 263 })
264 264
265 265 data = {
266 266 'more': False,
267 267 'results': res
268 268 }
269 269 return data
270 270
271 271 @LoginRequired()
272 272 @view_config(
273 273 route_name='goto_switcher_data', request_method='GET',
274 274 renderer='json_ext', xhr=True)
275 275 def goto_switcher_data(self):
276 276 c = self.load_default_context()
277 277
278 278 _ = self.request.translate
279 279
280 280 query = self.request.GET.get('query')
281 281 log.debug('generating main filter data, query %s', query)
282 282
283 283 default_search_val = 'Full text search for: `{}`'.format(query)
284 284 res = []
285 285 if not query:
286 286 return {'suggestions': res}
287 287
288 288 res.append({
289 289 'id': -1,
290 290 'value': query,
291 291 'value_display': default_search_val,
292 292 'type': 'search',
293 293 'url': h.route_path(
294 294 'search', _query={'q': query})
295 295 })
296 296
297 297 repo_groups = self._get_repo_group_list(query)
298 298 for serialized_repo_group in repo_groups:
299 299 res.append(serialized_repo_group)
300 300
301 301 repos = self._get_repo_list(query)
302 302 for serialized_repo in repos:
303 303 res.append(serialized_repo)
304 304
305 305 # TODO(marcink): permissions for that ?
306 users = self._get_user_list(query)
307 for serialized_user in users:
308 res.append(serialized_user)
306 allowed_user_search = self._rhodecode_user.username != User.DEFAULT_USER
307 if allowed_user_search:
308 users = self._get_user_list(query)
309 for serialized_user in users:
310 res.append(serialized_user)
309 311
310 312 commits = self._get_hash_commit_list(c.auth_user, query)
311 313 if commits:
312 314 unique_repos = collections.OrderedDict()
313 315 for commit in commits:
314 316 repo_name = commit['repo']
315 317 unique_repos.setdefault(repo_name, []).append(commit)
316 318
317 319 for repo, commits in unique_repos.items():
318 320 for commit in commits:
319 321 res.append(commit)
320 322
321 323 return {'suggestions': res}
322 324
323 325 def _get_groups_and_repos(self, repo_group_id=None):
324 326 # repo groups groups
325 327 repo_group_list = RepoGroup.get_all_repo_groups(group_id=repo_group_id)
326 328 _perms = ['group.read', 'group.write', 'group.admin']
327 329 repo_group_list_acl = RepoGroupList(repo_group_list, perm_set=_perms)
328 330 repo_group_data = RepoGroupModel().get_repo_groups_as_dict(
329 331 repo_group_list=repo_group_list_acl, admin=False)
330 332
331 333 # repositories
332 334 repo_list = Repository.get_all_repos(group_id=repo_group_id)
333 335 _perms = ['repository.read', 'repository.write', 'repository.admin']
334 336 repo_list_acl = RepoList(repo_list, perm_set=_perms)
335 337 repo_data = RepoModel().get_repos_as_dict(
336 338 repo_list=repo_list_acl, admin=False)
337 339
338 340 return repo_data, repo_group_data
339 341
340 342 @LoginRequired()
341 343 @view_config(
342 344 route_name='home', request_method='GET',
343 345 renderer='rhodecode:templates/index.mako')
344 346 def main_page(self):
345 347 c = self.load_default_context()
346 348 c.repo_group = None
347 349
348 350 repo_data, repo_group_data = self._get_groups_and_repos()
349 351 # json used to render the grids
350 352 c.repos_data = json.dumps(repo_data)
351 353 c.repo_groups_data = json.dumps(repo_group_data)
352 354
353 355 return self._get_template_context(c)
354 356
355 357 @LoginRequired()
356 358 @HasRepoGroupPermissionAnyDecorator(
357 359 'group.read', 'group.write', 'group.admin')
358 360 @view_config(
359 361 route_name='repo_group_home', request_method='GET',
360 362 renderer='rhodecode:templates/index_repo_group.mako')
361 363 @view_config(
362 364 route_name='repo_group_home_slash', request_method='GET',
363 365 renderer='rhodecode:templates/index_repo_group.mako')
364 366 def repo_group_main_page(self):
365 367 c = self.load_default_context()
366 368 c.repo_group = self.request.db_repo_group
367 369 repo_data, repo_group_data = self._get_groups_and_repos(
368 370 c.repo_group.group_id)
369 371
370 372 # json used to render the grids
371 373 c.repos_data = json.dumps(repo_data)
372 374 c.repo_groups_data = json.dumps(repo_group_data)
373 375
374 376 return self._get_template_context(c)
General Comments 0
You need to be logged in to leave comments. Login now