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