##// END OF EJS Templates
use password obfuscate in when clonning a remote repo with credentials
marcink -
r3452:d778ed1c beta
parent child Browse files
Show More
@@ -1,701 +1,700 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.repo
3 rhodecode.model.repo
4 ~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~
5
5
6 Repository model for rhodecode
6 Repository model for rhodecode
7
7
8 :created_on: Jun 5, 2010
8 :created_on: Jun 5, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 from __future__ import with_statement
25 from __future__ import with_statement
26 import os
26 import os
27 import shutil
27 import shutil
28 import logging
28 import logging
29 import traceback
29 import traceback
30 from datetime import datetime
30 from datetime import datetime
31
31
32 from rhodecode.lib.vcs.backends import get_backend
32 from rhodecode.lib.vcs.backends import get_backend
33 from rhodecode.lib.compat import json
33 from rhodecode.lib.compat import json
34 from rhodecode.lib.utils2 import LazyProperty, safe_str, safe_unicode,\
34 from rhodecode.lib.utils2 import LazyProperty, safe_str, safe_unicode,\
35 remove_prefix
35 remove_prefix, obfuscate_url_pw
36 from rhodecode.lib.caching_query import FromCache
36 from rhodecode.lib.caching_query import FromCache
37 from rhodecode.lib.hooks import log_create_repository, log_delete_repository
37 from rhodecode.lib.hooks import log_create_repository, log_delete_repository
38
38
39 from rhodecode.model import BaseModel
39 from rhodecode.model import BaseModel
40 from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \
40 from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \
41 Statistics, UserGroup, UserGroupRepoToPerm, RhodeCodeUi, RepoGroup,\
41 Statistics, UserGroup, UserGroupRepoToPerm, RhodeCodeUi, RepoGroup,\
42 RhodeCodeSetting, RepositoryField
42 RhodeCodeSetting, RepositoryField
43 from rhodecode.lib import helpers as h
43 from rhodecode.lib import helpers as h
44 from rhodecode.lib.auth import HasRepoPermissionAny
44 from rhodecode.lib.auth import HasRepoPermissionAny
45 from rhodecode.lib.vcs.backends.base import EmptyChangeset
46
47
45
48 log = logging.getLogger(__name__)
46 log = logging.getLogger(__name__)
49
47
50
48
51 class RepoModel(BaseModel):
49 class RepoModel(BaseModel):
52
50
53 cls = Repository
51 cls = Repository
54 URL_SEPARATOR = Repository.url_sep()
52 URL_SEPARATOR = Repository.url_sep()
55
53
56 def __get_users_group(self, users_group):
54 def __get_users_group(self, users_group):
57 return self._get_instance(UserGroup, users_group,
55 return self._get_instance(UserGroup, users_group,
58 callback=UserGroup.get_by_group_name)
56 callback=UserGroup.get_by_group_name)
59
57
60 def _get_repos_group(self, repos_group):
58 def _get_repos_group(self, repos_group):
61 return self._get_instance(RepoGroup, repos_group,
59 return self._get_instance(RepoGroup, repos_group,
62 callback=RepoGroup.get_by_group_name)
60 callback=RepoGroup.get_by_group_name)
63
61
64 @LazyProperty
62 @LazyProperty
65 def repos_path(self):
63 def repos_path(self):
66 """
64 """
67 Get's the repositories root path from database
65 Get's the repositories root path from database
68 """
66 """
69
67
70 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
68 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
71 return q.ui_value
69 return q.ui_value
72
70
73 def get(self, repo_id, cache=False):
71 def get(self, repo_id, cache=False):
74 repo = self.sa.query(Repository)\
72 repo = self.sa.query(Repository)\
75 .filter(Repository.repo_id == repo_id)
73 .filter(Repository.repo_id == repo_id)
76
74
77 if cache:
75 if cache:
78 repo = repo.options(FromCache("sql_cache_short",
76 repo = repo.options(FromCache("sql_cache_short",
79 "get_repo_%s" % repo_id))
77 "get_repo_%s" % repo_id))
80 return repo.scalar()
78 return repo.scalar()
81
79
82 def get_repo(self, repository):
80 def get_repo(self, repository):
83 return self._get_repo(repository)
81 return self._get_repo(repository)
84
82
85 def get_by_repo_name(self, repo_name, cache=False):
83 def get_by_repo_name(self, repo_name, cache=False):
86 repo = self.sa.query(Repository)\
84 repo = self.sa.query(Repository)\
87 .filter(Repository.repo_name == repo_name)
85 .filter(Repository.repo_name == repo_name)
88
86
89 if cache:
87 if cache:
90 repo = repo.options(FromCache("sql_cache_short",
88 repo = repo.options(FromCache("sql_cache_short",
91 "get_repo_%s" % repo_name))
89 "get_repo_%s" % repo_name))
92 return repo.scalar()
90 return repo.scalar()
93
91
94 def get_all_user_repos(self, user):
92 def get_all_user_repos(self, user):
95 """
93 """
96 Get's all repositories that user have at least read access
94 Get's all repositories that user have at least read access
97
95
98 :param user:
96 :param user:
99 :type user:
97 :type user:
100 """
98 """
101 from rhodecode.lib.auth import AuthUser
99 from rhodecode.lib.auth import AuthUser
102 user = self._get_user(user)
100 user = self._get_user(user)
103 repos = AuthUser(user_id=user.user_id).permissions['repositories']
101 repos = AuthUser(user_id=user.user_id).permissions['repositories']
104 access_check = lambda r: r[1] in ['repository.read',
102 access_check = lambda r: r[1] in ['repository.read',
105 'repository.write',
103 'repository.write',
106 'repository.admin']
104 'repository.admin']
107 repos = [x[0] for x in filter(access_check, repos.items())]
105 repos = [x[0] for x in filter(access_check, repos.items())]
108 return Repository.query().filter(Repository.repo_name.in_(repos))
106 return Repository.query().filter(Repository.repo_name.in_(repos))
109
107
110 def get_users_js(self):
108 def get_users_js(self):
111 users = self.sa.query(User).filter(User.active == True).all()
109 users = self.sa.query(User).filter(User.active == True).all()
112 return json.dumps([
110 return json.dumps([
113 {
111 {
114 'id': u.user_id,
112 'id': u.user_id,
115 'fname': u.name,
113 'fname': u.name,
116 'lname': u.lastname,
114 'lname': u.lastname,
117 'nname': u.username,
115 'nname': u.username,
118 'gravatar_lnk': h.gravatar_url(u.email, 14)
116 'gravatar_lnk': h.gravatar_url(u.email, 14)
119 } for u in users]
117 } for u in users]
120 )
118 )
121
119
122 def get_users_groups_js(self):
120 def get_users_groups_js(self):
123 users_groups = self.sa.query(UserGroup)\
121 users_groups = self.sa.query(UserGroup)\
124 .filter(UserGroup.users_group_active == True).all()
122 .filter(UserGroup.users_group_active == True).all()
125
123
126 return json.dumps([
124 return json.dumps([
127 {
125 {
128 'id': gr.users_group_id,
126 'id': gr.users_group_id,
129 'grname': gr.users_group_name,
127 'grname': gr.users_group_name,
130 'grmembers': len(gr.members),
128 'grmembers': len(gr.members),
131 } for gr in users_groups]
129 } for gr in users_groups]
132 )
130 )
133
131
134 @classmethod
132 @classmethod
135 def _render_datatable(cls, tmpl, *args, **kwargs):
133 def _render_datatable(cls, tmpl, *args, **kwargs):
136 import rhodecode
134 import rhodecode
137 from pylons import tmpl_context as c
135 from pylons import tmpl_context as c
138 from pylons.i18n.translation import _
136 from pylons.i18n.translation import _
139
137
140 _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
138 _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
141 template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
139 template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
142
140
143 tmpl = template.get_def(tmpl)
141 tmpl = template.get_def(tmpl)
144 kwargs.update(dict(_=_, h=h, c=c))
142 kwargs.update(dict(_=_, h=h, c=c))
145 return tmpl.render(*args, **kwargs)
143 return tmpl.render(*args, **kwargs)
146
144
147 @classmethod
145 @classmethod
148 def update_repoinfo(cls, repositories=None):
146 def update_repoinfo(cls, repositories=None):
149 if not repositories:
147 if not repositories:
150 repositories = Repository.getAll()
148 repositories = Repository.getAll()
151 for repo in repositories:
149 for repo in repositories:
152 repo.update_changeset_cache()
150 repo.update_changeset_cache()
153
151
154 def get_repos_as_dict(self, repos_list=None, admin=False, perm_check=True,
152 def get_repos_as_dict(self, repos_list=None, admin=False, perm_check=True,
155 super_user_actions=False):
153 super_user_actions=False):
156 _render = self._render_datatable
154 _render = self._render_datatable
157
155
158 def quick_menu(repo_name):
156 def quick_menu(repo_name):
159 return _render('quick_menu', repo_name)
157 return _render('quick_menu', repo_name)
160
158
161 def repo_lnk(name, rtype, private, fork_of):
159 def repo_lnk(name, rtype, private, fork_of):
162 return _render('repo_name', name, rtype, private, fork_of,
160 return _render('repo_name', name, rtype, private, fork_of,
163 short_name=not admin, admin=False)
161 short_name=not admin, admin=False)
164
162
165 def last_change(last_change):
163 def last_change(last_change):
166 return _render("last_change", last_change)
164 return _render("last_change", last_change)
167
165
168 def rss_lnk(repo_name):
166 def rss_lnk(repo_name):
169 return _render("rss", repo_name)
167 return _render("rss", repo_name)
170
168
171 def atom_lnk(repo_name):
169 def atom_lnk(repo_name):
172 return _render("atom", repo_name)
170 return _render("atom", repo_name)
173
171
174 def last_rev(repo_name, cs_cache):
172 def last_rev(repo_name, cs_cache):
175 return _render('revision', repo_name, cs_cache.get('revision'),
173 return _render('revision', repo_name, cs_cache.get('revision'),
176 cs_cache.get('raw_id'), cs_cache.get('author'),
174 cs_cache.get('raw_id'), cs_cache.get('author'),
177 cs_cache.get('message'))
175 cs_cache.get('message'))
178
176
179 def desc(desc):
177 def desc(desc):
180 from pylons import tmpl_context as c
178 from pylons import tmpl_context as c
181 if c.visual.stylify_metatags:
179 if c.visual.stylify_metatags:
182 return h.urlify_text(h.desc_stylize(h.truncate(desc, 60)))
180 return h.urlify_text(h.desc_stylize(h.truncate(desc, 60)))
183 else:
181 else:
184 return h.urlify_text(h.truncate(desc, 60))
182 return h.urlify_text(h.truncate(desc, 60))
185
183
186 def repo_actions(repo_name):
184 def repo_actions(repo_name):
187 return _render('repo_actions', repo_name, super_user_actions)
185 return _render('repo_actions', repo_name, super_user_actions)
188
186
189 def owner_actions(user_id, username):
187 def owner_actions(user_id, username):
190 return _render('user_name', user_id, username)
188 return _render('user_name', user_id, username)
191
189
192 repos_data = []
190 repos_data = []
193 for repo in repos_list:
191 for repo in repos_list:
194 if perm_check:
192 if perm_check:
195 # check permission at this level
193 # check permission at this level
196 if not HasRepoPermissionAny(
194 if not HasRepoPermissionAny(
197 'repository.read', 'repository.write', 'repository.admin'
195 'repository.read', 'repository.write', 'repository.admin'
198 )(repo.repo_name, 'get_repos_as_dict check'):
196 )(repo.repo_name, 'get_repos_as_dict check'):
199 continue
197 continue
200 cs_cache = repo.changeset_cache
198 cs_cache = repo.changeset_cache
201 row = {
199 row = {
202 "menu": quick_menu(repo.repo_name),
200 "menu": quick_menu(repo.repo_name),
203 "raw_name": repo.repo_name.lower(),
201 "raw_name": repo.repo_name.lower(),
204 "name": repo_lnk(repo.repo_name, repo.repo_type,
202 "name": repo_lnk(repo.repo_name, repo.repo_type,
205 repo.private, repo.fork),
203 repo.private, repo.fork),
206 "last_change": last_change(repo.last_db_change),
204 "last_change": last_change(repo.last_db_change),
207 "last_changeset": last_rev(repo.repo_name, cs_cache),
205 "last_changeset": last_rev(repo.repo_name, cs_cache),
208 "raw_tip": cs_cache.get('revision'),
206 "raw_tip": cs_cache.get('revision'),
209 "desc": desc(repo.description),
207 "desc": desc(repo.description),
210 "owner": h.person(repo.user.username),
208 "owner": h.person(repo.user.username),
211 "rss": rss_lnk(repo.repo_name),
209 "rss": rss_lnk(repo.repo_name),
212 "atom": atom_lnk(repo.repo_name),
210 "atom": atom_lnk(repo.repo_name),
213
211
214 }
212 }
215 if admin:
213 if admin:
216 row.update({
214 row.update({
217 "action": repo_actions(repo.repo_name),
215 "action": repo_actions(repo.repo_name),
218 "owner": owner_actions(repo.user.user_id,
216 "owner": owner_actions(repo.user.user_id,
219 h.person(repo.user.username))
217 h.person(repo.user.username))
220 })
218 })
221 repos_data.append(row)
219 repos_data.append(row)
222
220
223 return {
221 return {
224 "totalRecords": len(repos_list),
222 "totalRecords": len(repos_list),
225 "startIndex": 0,
223 "startIndex": 0,
226 "sort": "name",
224 "sort": "name",
227 "dir": "asc",
225 "dir": "asc",
228 "records": repos_data
226 "records": repos_data
229 }
227 }
230
228
231 def _get_defaults(self, repo_name):
229 def _get_defaults(self, repo_name):
232 """
230 """
233 Get's information about repository, and returns a dict for
231 Get's information about repository, and returns a dict for
234 usage in forms
232 usage in forms
235
233
236 :param repo_name:
234 :param repo_name:
237 """
235 """
238
236
239 repo_info = Repository.get_by_repo_name(repo_name)
237 repo_info = Repository.get_by_repo_name(repo_name)
240
238
241 if repo_info is None:
239 if repo_info is None:
242 return None
240 return None
243
241
244 defaults = repo_info.get_dict()
242 defaults = repo_info.get_dict()
245 group, repo_name = repo_info.groups_and_repo
243 group, repo_name = repo_info.groups_and_repo
246 defaults['repo_name'] = repo_name
244 defaults['repo_name'] = repo_name
247 defaults['repo_group'] = getattr(group[-1] if group else None,
245 defaults['repo_group'] = getattr(group[-1] if group else None,
248 'group_id', None)
246 'group_id', None)
249
247
250 for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'),
248 for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'),
251 (1, 'repo_description'), (1, 'repo_enable_locking'),
249 (1, 'repo_description'), (1, 'repo_enable_locking'),
252 (1, 'repo_landing_rev'), (0, 'clone_uri'),
250 (1, 'repo_landing_rev'), (0, 'clone_uri'),
253 (1, 'repo_private'), (1, 'repo_enable_statistics')]:
251 (1, 'repo_private'), (1, 'repo_enable_statistics')]:
254 attr = k
252 attr = k
255 if strip:
253 if strip:
256 attr = remove_prefix(k, 'repo_')
254 attr = remove_prefix(k, 'repo_')
257
255
258 defaults[k] = defaults[attr]
256 defaults[k] = defaults[attr]
259
257
260 # fill owner
258 # fill owner
261 if repo_info.user:
259 if repo_info.user:
262 defaults.update({'user': repo_info.user.username})
260 defaults.update({'user': repo_info.user.username})
263 else:
261 else:
264 replacement_user = User.query().filter(User.admin ==
262 replacement_user = User.query().filter(User.admin ==
265 True).first().username
263 True).first().username
266 defaults.update({'user': replacement_user})
264 defaults.update({'user': replacement_user})
267
265
268 # fill repository users
266 # fill repository users
269 for p in repo_info.repo_to_perm:
267 for p in repo_info.repo_to_perm:
270 defaults.update({'u_perm_%s' % p.user.username:
268 defaults.update({'u_perm_%s' % p.user.username:
271 p.permission.permission_name})
269 p.permission.permission_name})
272
270
273 # fill repository groups
271 # fill repository groups
274 for p in repo_info.users_group_to_perm:
272 for p in repo_info.users_group_to_perm:
275 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
273 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
276 p.permission.permission_name})
274 p.permission.permission_name})
277
275
278 return defaults
276 return defaults
279
277
280 def update(self, org_repo_name, **kwargs):
278 def update(self, org_repo_name, **kwargs):
281 try:
279 try:
282 cur_repo = self.get_by_repo_name(org_repo_name, cache=False)
280 cur_repo = self.get_by_repo_name(org_repo_name, cache=False)
283
281
284 # update permissions
282 # update permissions
285 for member, perm, member_type in kwargs['perms_updates']:
283 for member, perm, member_type in kwargs['perms_updates']:
286 if member_type == 'user':
284 if member_type == 'user':
287 # this updates existing one
285 # this updates existing one
288 RepoModel().grant_user_permission(
286 RepoModel().grant_user_permission(
289 repo=cur_repo, user=member, perm=perm
287 repo=cur_repo, user=member, perm=perm
290 )
288 )
291 else:
289 else:
292 RepoModel().grant_users_group_permission(
290 RepoModel().grant_users_group_permission(
293 repo=cur_repo, group_name=member, perm=perm
291 repo=cur_repo, group_name=member, perm=perm
294 )
292 )
295 # set new permissions
293 # set new permissions
296 for member, perm, member_type in kwargs['perms_new']:
294 for member, perm, member_type in kwargs['perms_new']:
297 if member_type == 'user':
295 if member_type == 'user':
298 RepoModel().grant_user_permission(
296 RepoModel().grant_user_permission(
299 repo=cur_repo, user=member, perm=perm
297 repo=cur_repo, user=member, perm=perm
300 )
298 )
301 else:
299 else:
302 RepoModel().grant_users_group_permission(
300 RepoModel().grant_users_group_permission(
303 repo=cur_repo, group_name=member, perm=perm
301 repo=cur_repo, group_name=member, perm=perm
304 )
302 )
305
303
306 if 'user' in kwargs:
304 if 'user' in kwargs:
307 cur_repo.user = User.get_by_username(kwargs['user'])
305 cur_repo.user = User.get_by_username(kwargs['user'])
308
306
309 if 'repo_group' in kwargs:
307 if 'repo_group' in kwargs:
310 cur_repo.group = RepoGroup.get(kwargs['repo_group'])
308 cur_repo.group = RepoGroup.get(kwargs['repo_group'])
311
309
312 for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'),
310 for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'),
313 (1, 'repo_description'), (1, 'repo_enable_locking'),
311 (1, 'repo_description'), (1, 'repo_enable_locking'),
314 (1, 'repo_landing_rev'), (0, 'clone_uri'),
312 (1, 'repo_landing_rev'), (0, 'clone_uri'),
315 (1, 'repo_private'), (1, 'repo_enable_statistics')]:
313 (1, 'repo_private'), (1, 'repo_enable_statistics')]:
316 if k in kwargs:
314 if k in kwargs:
317 val = kwargs[k]
315 val = kwargs[k]
318 if strip:
316 if strip:
319 k = remove_prefix(k, 'repo_')
317 k = remove_prefix(k, 'repo_')
320 setattr(cur_repo, k, val)
318 setattr(cur_repo, k, val)
321
319
322 new_name = cur_repo.get_new_name(kwargs['repo_name'])
320 new_name = cur_repo.get_new_name(kwargs['repo_name'])
323 cur_repo.repo_name = new_name
321 cur_repo.repo_name = new_name
324
322
325 #handle extra fields
323 #handle extra fields
326 for field in filter(lambda k: k.startswith(RepositoryField.PREFIX), kwargs):
324 for field in filter(lambda k: k.startswith(RepositoryField.PREFIX), kwargs):
327 k = RepositoryField.un_prefix_key(field)
325 k = RepositoryField.un_prefix_key(field)
328 ex_field = RepositoryField.get_by_key_name(key=k, repo=cur_repo)
326 ex_field = RepositoryField.get_by_key_name(key=k, repo=cur_repo)
329 if ex_field:
327 if ex_field:
330 ex_field.field_value = kwargs[field]
328 ex_field.field_value = kwargs[field]
331 self.sa.add(ex_field)
329 self.sa.add(ex_field)
332 self.sa.add(cur_repo)
330 self.sa.add(cur_repo)
333
331
334 if org_repo_name != new_name:
332 if org_repo_name != new_name:
335 # rename repository
333 # rename repository
336 self.__rename_repo(old=org_repo_name, new=new_name)
334 self.__rename_repo(old=org_repo_name, new=new_name)
337
335
338 return cur_repo
336 return cur_repo
339 except:
337 except:
340 log.error(traceback.format_exc())
338 log.error(traceback.format_exc())
341 raise
339 raise
342
340
343 def create_repo(self, repo_name, repo_type, description, owner,
341 def create_repo(self, repo_name, repo_type, description, owner,
344 private=False, clone_uri=None, repos_group=None,
342 private=False, clone_uri=None, repos_group=None,
345 landing_rev='tip', just_db=False, fork_of=None,
343 landing_rev='tip', just_db=False, fork_of=None,
346 copy_fork_permissions=False, enable_statistics=False,
344 copy_fork_permissions=False, enable_statistics=False,
347 enable_locking=False, enable_downloads=False):
345 enable_locking=False, enable_downloads=False):
348 """
346 """
349 Create repository
347 Create repository
350
348
351 """
349 """
352 from rhodecode.model.scm import ScmModel
350 from rhodecode.model.scm import ScmModel
353
351
354 owner = self._get_user(owner)
352 owner = self._get_user(owner)
355 fork_of = self._get_repo(fork_of)
353 fork_of = self._get_repo(fork_of)
356 repos_group = self._get_repos_group(repos_group)
354 repos_group = self._get_repos_group(repos_group)
357 try:
355 try:
358
356
359 # repo name is just a name of repository
357 # repo name is just a name of repository
360 # while repo_name_full is a full qualified name that is combined
358 # while repo_name_full is a full qualified name that is combined
361 # with name and path of group
359 # with name and path of group
362 repo_name_full = repo_name
360 repo_name_full = repo_name
363 repo_name = repo_name.split(self.URL_SEPARATOR)[-1]
361 repo_name = repo_name.split(self.URL_SEPARATOR)[-1]
364
362
365 new_repo = Repository()
363 new_repo = Repository()
366 new_repo.enable_statistics = False
364 new_repo.enable_statistics = False
367 new_repo.repo_name = repo_name_full
365 new_repo.repo_name = repo_name_full
368 new_repo.repo_type = repo_type
366 new_repo.repo_type = repo_type
369 new_repo.user = owner
367 new_repo.user = owner
370 new_repo.group = repos_group
368 new_repo.group = repos_group
371 new_repo.description = description or repo_name
369 new_repo.description = description or repo_name
372 new_repo.private = private
370 new_repo.private = private
373 new_repo.clone_uri = clone_uri
371 new_repo.clone_uri = clone_uri
374 new_repo.landing_rev = landing_rev
372 new_repo.landing_rev = landing_rev
375
373
376 new_repo.enable_statistics = enable_statistics
374 new_repo.enable_statistics = enable_statistics
377 new_repo.enable_locking = enable_locking
375 new_repo.enable_locking = enable_locking
378 new_repo.enable_downloads = enable_downloads
376 new_repo.enable_downloads = enable_downloads
379
377
380 if repos_group:
378 if repos_group:
381 new_repo.enable_locking = repos_group.enable_locking
379 new_repo.enable_locking = repos_group.enable_locking
382
380
383 if fork_of:
381 if fork_of:
384 parent_repo = fork_of
382 parent_repo = fork_of
385 new_repo.fork = parent_repo
383 new_repo.fork = parent_repo
386
384
387 self.sa.add(new_repo)
385 self.sa.add(new_repo)
388
386
389 def _create_default_perms():
387 def _create_default_perms():
390 # create default permission
388 # create default permission
391 repo_to_perm = UserRepoToPerm()
389 repo_to_perm = UserRepoToPerm()
392 default = 'repository.read'
390 default = 'repository.read'
393 for p in User.get_by_username('default').user_perms:
391 for p in User.get_by_username('default').user_perms:
394 if p.permission.permission_name.startswith('repository.'):
392 if p.permission.permission_name.startswith('repository.'):
395 default = p.permission.permission_name
393 default = p.permission.permission_name
396 break
394 break
397
395
398 default_perm = 'repository.none' if private else default
396 default_perm = 'repository.none' if private else default
399
397
400 repo_to_perm.permission_id = self.sa.query(Permission)\
398 repo_to_perm.permission_id = self.sa.query(Permission)\
401 .filter(Permission.permission_name == default_perm)\
399 .filter(Permission.permission_name == default_perm)\
402 .one().permission_id
400 .one().permission_id
403
401
404 repo_to_perm.repository = new_repo
402 repo_to_perm.repository = new_repo
405 repo_to_perm.user_id = User.get_by_username('default').user_id
403 repo_to_perm.user_id = User.get_by_username('default').user_id
406
404
407 self.sa.add(repo_to_perm)
405 self.sa.add(repo_to_perm)
408
406
409 if fork_of:
407 if fork_of:
410 if copy_fork_permissions:
408 if copy_fork_permissions:
411 repo = fork_of
409 repo = fork_of
412 user_perms = UserRepoToPerm.query()\
410 user_perms = UserRepoToPerm.query()\
413 .filter(UserRepoToPerm.repository == repo).all()
411 .filter(UserRepoToPerm.repository == repo).all()
414 group_perms = UserGroupRepoToPerm.query()\
412 group_perms = UserGroupRepoToPerm.query()\
415 .filter(UserGroupRepoToPerm.repository == repo).all()
413 .filter(UserGroupRepoToPerm.repository == repo).all()
416
414
417 for perm in user_perms:
415 for perm in user_perms:
418 UserRepoToPerm.create(perm.user, new_repo,
416 UserRepoToPerm.create(perm.user, new_repo,
419 perm.permission)
417 perm.permission)
420
418
421 for perm in group_perms:
419 for perm in group_perms:
422 UserGroupRepoToPerm.create(perm.users_group, new_repo,
420 UserGroupRepoToPerm.create(perm.users_group, new_repo,
423 perm.permission)
421 perm.permission)
424 else:
422 else:
425 _create_default_perms()
423 _create_default_perms()
426 else:
424 else:
427 _create_default_perms()
425 _create_default_perms()
428
426
429 if not just_db:
427 if not just_db:
430 self.__create_repo(repo_name, repo_type,
428 self.__create_repo(repo_name, repo_type,
431 repos_group,
429 repos_group,
432 clone_uri)
430 clone_uri)
433 log_create_repository(new_repo.get_dict(),
431 log_create_repository(new_repo.get_dict(),
434 created_by=owner.username)
432 created_by=owner.username)
435
433
436 # now automatically start following this repository as owner
434 # now automatically start following this repository as owner
437 ScmModel(self.sa).toggle_following_repo(new_repo.repo_id,
435 ScmModel(self.sa).toggle_following_repo(new_repo.repo_id,
438 owner.user_id)
436 owner.user_id)
439 return new_repo
437 return new_repo
440 except:
438 except:
441 log.error(traceback.format_exc())
439 log.error(traceback.format_exc())
442 raise
440 raise
443
441
444 def create(self, form_data, cur_user, just_db=False, fork=None):
442 def create(self, form_data, cur_user, just_db=False, fork=None):
445 """
443 """
446 Backward compatibility function, just a wrapper on top of create_repo
444 Backward compatibility function, just a wrapper on top of create_repo
447
445
448 :param form_data:
446 :param form_data:
449 :param cur_user:
447 :param cur_user:
450 :param just_db:
448 :param just_db:
451 :param fork:
449 :param fork:
452 """
450 """
453 owner = cur_user
451 owner = cur_user
454 repo_name = form_data['repo_name_full']
452 repo_name = form_data['repo_name_full']
455 repo_type = form_data['repo_type']
453 repo_type = form_data['repo_type']
456 description = form_data['repo_description']
454 description = form_data['repo_description']
457 private = form_data['repo_private']
455 private = form_data['repo_private']
458 clone_uri = form_data.get('clone_uri')
456 clone_uri = form_data.get('clone_uri')
459 repos_group = form_data['repo_group']
457 repos_group = form_data['repo_group']
460 landing_rev = form_data['repo_landing_rev']
458 landing_rev = form_data['repo_landing_rev']
461 copy_fork_permissions = form_data.get('copy_permissions')
459 copy_fork_permissions = form_data.get('copy_permissions')
462 fork_of = form_data.get('fork_parent_id')
460 fork_of = form_data.get('fork_parent_id')
463
461
464 ## repo creation defaults, private and repo_type are filled in form
462 ## repo creation defaults, private and repo_type are filled in form
465 defs = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
463 defs = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
466 enable_statistics = defs.get('repo_enable_statistics')
464 enable_statistics = defs.get('repo_enable_statistics')
467 enable_locking = defs.get('repo_enable_locking')
465 enable_locking = defs.get('repo_enable_locking')
468 enable_downloads = defs.get('repo_enable_downloads')
466 enable_downloads = defs.get('repo_enable_downloads')
469
467
470 return self.create_repo(
468 return self.create_repo(
471 repo_name, repo_type, description, owner, private, clone_uri,
469 repo_name, repo_type, description, owner, private, clone_uri,
472 repos_group, landing_rev, just_db, fork_of, copy_fork_permissions,
470 repos_group, landing_rev, just_db, fork_of, copy_fork_permissions,
473 enable_statistics, enable_locking, enable_downloads
471 enable_statistics, enable_locking, enable_downloads
474 )
472 )
475
473
476 def create_fork(self, form_data, cur_user):
474 def create_fork(self, form_data, cur_user):
477 """
475 """
478 Simple wrapper into executing celery task for fork creation
476 Simple wrapper into executing celery task for fork creation
479
477
480 :param form_data:
478 :param form_data:
481 :param cur_user:
479 :param cur_user:
482 """
480 """
483 from rhodecode.lib.celerylib import tasks, run_task
481 from rhodecode.lib.celerylib import tasks, run_task
484 run_task(tasks.create_repo_fork, form_data, cur_user)
482 run_task(tasks.create_repo_fork, form_data, cur_user)
485
483
486 def delete(self, repo):
484 def delete(self, repo):
487 repo = self._get_repo(repo)
485 repo = self._get_repo(repo)
488 if repo:
486 if repo:
489 old_repo_dict = repo.get_dict()
487 old_repo_dict = repo.get_dict()
490 owner = repo.user
488 owner = repo.user
491 try:
489 try:
492 self.sa.delete(repo)
490 self.sa.delete(repo)
493 self.__delete_repo(repo)
491 self.__delete_repo(repo)
494 log_delete_repository(old_repo_dict,
492 log_delete_repository(old_repo_dict,
495 deleted_by=owner.username)
493 deleted_by=owner.username)
496 except:
494 except:
497 log.error(traceback.format_exc())
495 log.error(traceback.format_exc())
498 raise
496 raise
499
497
500 def grant_user_permission(self, repo, user, perm):
498 def grant_user_permission(self, repo, user, perm):
501 """
499 """
502 Grant permission for user on given repository, or update existing one
500 Grant permission for user on given repository, or update existing one
503 if found
501 if found
504
502
505 :param repo: Instance of Repository, repository_id, or repository name
503 :param repo: Instance of Repository, repository_id, or repository name
506 :param user: Instance of User, user_id or username
504 :param user: Instance of User, user_id or username
507 :param perm: Instance of Permission, or permission_name
505 :param perm: Instance of Permission, or permission_name
508 """
506 """
509 user = self._get_user(user)
507 user = self._get_user(user)
510 repo = self._get_repo(repo)
508 repo = self._get_repo(repo)
511 permission = self._get_perm(perm)
509 permission = self._get_perm(perm)
512
510
513 # check if we have that permission already
511 # check if we have that permission already
514 obj = self.sa.query(UserRepoToPerm)\
512 obj = self.sa.query(UserRepoToPerm)\
515 .filter(UserRepoToPerm.user == user)\
513 .filter(UserRepoToPerm.user == user)\
516 .filter(UserRepoToPerm.repository == repo)\
514 .filter(UserRepoToPerm.repository == repo)\
517 .scalar()
515 .scalar()
518 if obj is None:
516 if obj is None:
519 # create new !
517 # create new !
520 obj = UserRepoToPerm()
518 obj = UserRepoToPerm()
521 obj.repository = repo
519 obj.repository = repo
522 obj.user = user
520 obj.user = user
523 obj.permission = permission
521 obj.permission = permission
524 self.sa.add(obj)
522 self.sa.add(obj)
525 log.debug('Granted perm %s to %s on %s' % (perm, user, repo))
523 log.debug('Granted perm %s to %s on %s' % (perm, user, repo))
526
524
527 def revoke_user_permission(self, repo, user):
525 def revoke_user_permission(self, repo, user):
528 """
526 """
529 Revoke permission for user on given repository
527 Revoke permission for user on given repository
530
528
531 :param repo: Instance of Repository, repository_id, or repository name
529 :param repo: Instance of Repository, repository_id, or repository name
532 :param user: Instance of User, user_id or username
530 :param user: Instance of User, user_id or username
533 """
531 """
534
532
535 user = self._get_user(user)
533 user = self._get_user(user)
536 repo = self._get_repo(repo)
534 repo = self._get_repo(repo)
537
535
538 obj = self.sa.query(UserRepoToPerm)\
536 obj = self.sa.query(UserRepoToPerm)\
539 .filter(UserRepoToPerm.repository == repo)\
537 .filter(UserRepoToPerm.repository == repo)\
540 .filter(UserRepoToPerm.user == user)\
538 .filter(UserRepoToPerm.user == user)\
541 .scalar()
539 .scalar()
542 if obj:
540 if obj:
543 self.sa.delete(obj)
541 self.sa.delete(obj)
544 log.debug('Revoked perm on %s on %s' % (repo, user))
542 log.debug('Revoked perm on %s on %s' % (repo, user))
545
543
546 def grant_users_group_permission(self, repo, group_name, perm):
544 def grant_users_group_permission(self, repo, group_name, perm):
547 """
545 """
548 Grant permission for user group on given repository, or update
546 Grant permission for user group on given repository, or update
549 existing one if found
547 existing one if found
550
548
551 :param repo: Instance of Repository, repository_id, or repository name
549 :param repo: Instance of Repository, repository_id, or repository name
552 :param group_name: Instance of UserGroup, users_group_id,
550 :param group_name: Instance of UserGroup, users_group_id,
553 or user group name
551 or user group name
554 :param perm: Instance of Permission, or permission_name
552 :param perm: Instance of Permission, or permission_name
555 """
553 """
556 repo = self._get_repo(repo)
554 repo = self._get_repo(repo)
557 group_name = self.__get_users_group(group_name)
555 group_name = self.__get_users_group(group_name)
558 permission = self._get_perm(perm)
556 permission = self._get_perm(perm)
559
557
560 # check if we have that permission already
558 # check if we have that permission already
561 obj = self.sa.query(UserGroupRepoToPerm)\
559 obj = self.sa.query(UserGroupRepoToPerm)\
562 .filter(UserGroupRepoToPerm.users_group == group_name)\
560 .filter(UserGroupRepoToPerm.users_group == group_name)\
563 .filter(UserGroupRepoToPerm.repository == repo)\
561 .filter(UserGroupRepoToPerm.repository == repo)\
564 .scalar()
562 .scalar()
565
563
566 if obj is None:
564 if obj is None:
567 # create new
565 # create new
568 obj = UserGroupRepoToPerm()
566 obj = UserGroupRepoToPerm()
569
567
570 obj.repository = repo
568 obj.repository = repo
571 obj.users_group = group_name
569 obj.users_group = group_name
572 obj.permission = permission
570 obj.permission = permission
573 self.sa.add(obj)
571 self.sa.add(obj)
574 log.debug('Granted perm %s to %s on %s' % (perm, group_name, repo))
572 log.debug('Granted perm %s to %s on %s' % (perm, group_name, repo))
575
573
576 def revoke_users_group_permission(self, repo, group_name):
574 def revoke_users_group_permission(self, repo, group_name):
577 """
575 """
578 Revoke permission for user group on given repository
576 Revoke permission for user group on given repository
579
577
580 :param repo: Instance of Repository, repository_id, or repository name
578 :param repo: Instance of Repository, repository_id, or repository name
581 :param group_name: Instance of UserGroup, users_group_id,
579 :param group_name: Instance of UserGroup, users_group_id,
582 or user group name
580 or user group name
583 """
581 """
584 repo = self._get_repo(repo)
582 repo = self._get_repo(repo)
585 group_name = self.__get_users_group(group_name)
583 group_name = self.__get_users_group(group_name)
586
584
587 obj = self.sa.query(UserGroupRepoToPerm)\
585 obj = self.sa.query(UserGroupRepoToPerm)\
588 .filter(UserGroupRepoToPerm.repository == repo)\
586 .filter(UserGroupRepoToPerm.repository == repo)\
589 .filter(UserGroupRepoToPerm.users_group == group_name)\
587 .filter(UserGroupRepoToPerm.users_group == group_name)\
590 .scalar()
588 .scalar()
591 if obj:
589 if obj:
592 self.sa.delete(obj)
590 self.sa.delete(obj)
593 log.debug('Revoked perm to %s on %s' % (repo, group_name))
591 log.debug('Revoked perm to %s on %s' % (repo, group_name))
594
592
595 def delete_stats(self, repo_name):
593 def delete_stats(self, repo_name):
596 """
594 """
597 removes stats for given repo
595 removes stats for given repo
598
596
599 :param repo_name:
597 :param repo_name:
600 """
598 """
601 repo = self._get_repo(repo_name)
599 repo = self._get_repo(repo_name)
602 try:
600 try:
603 obj = self.sa.query(Statistics)\
601 obj = self.sa.query(Statistics)\
604 .filter(Statistics.repository == repo).scalar()
602 .filter(Statistics.repository == repo).scalar()
605 if obj:
603 if obj:
606 self.sa.delete(obj)
604 self.sa.delete(obj)
607 except:
605 except:
608 log.error(traceback.format_exc())
606 log.error(traceback.format_exc())
609 raise
607 raise
610
608
611 def __create_repo(self, repo_name, alias, parent, clone_uri=False):
609 def __create_repo(self, repo_name, alias, parent, clone_uri=False):
612 """
610 """
613 makes repository on filesystem. It's group aware means it'll create
611 makes repository on filesystem. It's group aware means it'll create
614 a repository within a group, and alter the paths accordingly of
612 a repository within a group, and alter the paths accordingly of
615 group location
613 group location
616
614
617 :param repo_name:
615 :param repo_name:
618 :param alias:
616 :param alias:
619 :param parent_id:
617 :param parent_id:
620 :param clone_uri:
618 :param clone_uri:
621 """
619 """
622 from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group
620 from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group
623 from rhodecode.model.scm import ScmModel
621 from rhodecode.model.scm import ScmModel
624
622
625 if parent:
623 if parent:
626 new_parent_path = os.sep.join(parent.full_path_splitted)
624 new_parent_path = os.sep.join(parent.full_path_splitted)
627 else:
625 else:
628 new_parent_path = ''
626 new_parent_path = ''
629
627
630 # we need to make it str for mercurial
628 # we need to make it str for mercurial
631 repo_path = os.path.join(*map(lambda x: safe_str(x),
629 repo_path = os.path.join(*map(lambda x: safe_str(x),
632 [self.repos_path, new_parent_path, repo_name]))
630 [self.repos_path, new_parent_path, repo_name]))
633
631
634 # check if this path is not a repository
632 # check if this path is not a repository
635 if is_valid_repo(repo_path, self.repos_path):
633 if is_valid_repo(repo_path, self.repos_path):
636 raise Exception('This path %s is a valid repository' % repo_path)
634 raise Exception('This path %s is a valid repository' % repo_path)
637
635
638 # check if this path is a group
636 # check if this path is a group
639 if is_valid_repos_group(repo_path, self.repos_path):
637 if is_valid_repos_group(repo_path, self.repos_path):
640 raise Exception('This path %s is a valid group' % repo_path)
638 raise Exception('This path %s is a valid group' % repo_path)
641
639
642 log.info('creating repo %s in %s @ %s' % (
640 log.info('creating repo %s in %s @ %s' % (
643 repo_name, safe_unicode(repo_path), clone_uri
641 repo_name, safe_unicode(repo_path),
642 obfuscate_url_pw(clone_uri)
644 )
643 )
645 )
644 )
646 backend = get_backend(alias)
645 backend = get_backend(alias)
647 if alias == 'hg':
646 if alias == 'hg':
648 backend(repo_path, create=True, src_url=clone_uri)
647 backend(repo_path, create=True, src_url=clone_uri)
649 elif alias == 'git':
648 elif alias == 'git':
650 r = backend(repo_path, create=True, src_url=clone_uri, bare=True)
649 r = backend(repo_path, create=True, src_url=clone_uri, bare=True)
651 # add rhodecode hook into this repo
650 # add rhodecode hook into this repo
652 ScmModel().install_git_hook(repo=r)
651 ScmModel().install_git_hook(repo=r)
653 else:
652 else:
654 raise Exception('Undefined alias %s' % alias)
653 raise Exception('Undefined alias %s' % alias)
655
654
656 def __rename_repo(self, old, new):
655 def __rename_repo(self, old, new):
657 """
656 """
658 renames repository on filesystem
657 renames repository on filesystem
659
658
660 :param old: old name
659 :param old: old name
661 :param new: new name
660 :param new: new name
662 """
661 """
663 log.info('renaming repo from %s to %s' % (old, new))
662 log.info('renaming repo from %s to %s' % (old, new))
664
663
665 old_path = os.path.join(self.repos_path, old)
664 old_path = os.path.join(self.repos_path, old)
666 new_path = os.path.join(self.repos_path, new)
665 new_path = os.path.join(self.repos_path, new)
667 if os.path.isdir(new_path):
666 if os.path.isdir(new_path):
668 raise Exception(
667 raise Exception(
669 'Was trying to rename to already existing dir %s' % new_path
668 'Was trying to rename to already existing dir %s' % new_path
670 )
669 )
671 shutil.move(old_path, new_path)
670 shutil.move(old_path, new_path)
672
671
673 def __delete_repo(self, repo):
672 def __delete_repo(self, repo):
674 """
673 """
675 removes repo from filesystem, the removal is acctually made by
674 removes repo from filesystem, the removal is acctually made by
676 added rm__ prefix into dir, and rename internat .hg/.git dirs so this
675 added rm__ prefix into dir, and rename internat .hg/.git dirs so this
677 repository is no longer valid for rhodecode, can be undeleted later on
676 repository is no longer valid for rhodecode, can be undeleted later on
678 by reverting the renames on this repository
677 by reverting the renames on this repository
679
678
680 :param repo: repo object
679 :param repo: repo object
681 """
680 """
682 rm_path = os.path.join(self.repos_path, repo.repo_name)
681 rm_path = os.path.join(self.repos_path, repo.repo_name)
683 log.info("Removing %s" % (rm_path))
682 log.info("Removing %s" % (rm_path))
684 # disable hg/git internal that it doesn't get detected as repo
683 # disable hg/git internal that it doesn't get detected as repo
685 alias = repo.repo_type
684 alias = repo.repo_type
686
685
687 bare = getattr(repo.scm_instance, 'bare', False)
686 bare = getattr(repo.scm_instance, 'bare', False)
688
687
689 if not bare:
688 if not bare:
690 # skip this for bare git repos
689 # skip this for bare git repos
691 shutil.move(os.path.join(rm_path, '.%s' % alias),
690 shutil.move(os.path.join(rm_path, '.%s' % alias),
692 os.path.join(rm_path, 'rm__.%s' % alias))
691 os.path.join(rm_path, 'rm__.%s' % alias))
693 # disable repo
692 # disable repo
694 _now = datetime.now()
693 _now = datetime.now()
695 _ms = str(_now.microsecond).rjust(6, '0')
694 _ms = str(_now.microsecond).rjust(6, '0')
696 _d = 'rm__%s__%s' % (_now.strftime('%Y%m%d_%H%M%S_' + _ms),
695 _d = 'rm__%s__%s' % (_now.strftime('%Y%m%d_%H%M%S_' + _ms),
697 repo.just_name)
696 repo.just_name)
698 if repo.group:
697 if repo.group:
699 args = repo.group.full_path_splitted + [_d]
698 args = repo.group.full_path_splitted + [_d]
700 _d = os.path.join(*args)
699 _d = os.path.join(*args)
701 shutil.move(rm_path, os.path.join(self.repos_path, _d))
700 shutil.move(rm_path, os.path.join(self.repos_path, _d))
General Comments 0
You need to be logged in to leave comments. Login now