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