##// END OF EJS Templates
permission fixes for forking
marcink -
r1060:97ed582e beta
parent child Browse files
Show More
@@ -1,206 +1,208 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.settings
3 rhodecode.controllers.settings
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Settings controller for rhodecode
6 Settings controller for rhodecode
7
7
8 :created_on: Jun 30, 2010
8 :created_on: Jun 30, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 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
13 # This program is free software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
15 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
16 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
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, write to the Free Software
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
27
27
28 import logging
28 import logging
29 import traceback
29 import traceback
30
30
31 import formencode
31 import formencode
32
32
33 from pylons import tmpl_context as c, request, url
33 from pylons import tmpl_context as c, request, url
34 from pylons.controllers.util import redirect
34 from pylons.controllers.util import redirect
35 from pylons.i18n.translation import _
35 from pylons.i18n.translation import _
36
36
37 import rhodecode.lib.helpers as h
37 import rhodecode.lib.helpers as h
38
38
39 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAllDecorator, \
39 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAllDecorator, \
40 NotAnonymous
40 HasRepoPermissionAnyDecorator, NotAnonymous
41 from rhodecode.lib.base import BaseRepoController, render
41 from rhodecode.lib.base import BaseRepoController, render
42 from rhodecode.lib.utils import invalidate_cache, action_logger
42 from rhodecode.lib.utils import invalidate_cache, action_logger
43
43
44 from rhodecode.model.forms import RepoSettingsForm, RepoForkForm
44 from rhodecode.model.forms import RepoSettingsForm, RepoForkForm
45 from rhodecode.model.repo import RepoModel
45 from rhodecode.model.repo import RepoModel
46 from rhodecode.model.db import User
46 from rhodecode.model.db import User
47
47
48 log = logging.getLogger(__name__)
48 log = logging.getLogger(__name__)
49
49
50 class SettingsController(BaseRepoController):
50 class SettingsController(BaseRepoController):
51
51
52 @LoginRequired()
52 @LoginRequired()
53 def __before__(self):
53 def __before__(self):
54 super(SettingsController, self).__before__()
54 super(SettingsController, self).__before__()
55
55
56 @HasRepoPermissionAllDecorator('repository.admin')
56 @HasRepoPermissionAllDecorator('repository.admin')
57 def index(self, repo_name):
57 def index(self, repo_name):
58 repo_model = RepoModel()
58 repo_model = RepoModel()
59 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
59 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
60 if not repo:
60 if not repo:
61 h.flash(_('%s repository is not mapped to db perhaps'
61 h.flash(_('%s repository is not mapped to db perhaps'
62 ' it was created or renamed from the file system'
62 ' it was created or renamed from the file system'
63 ' please run the application again'
63 ' please run the application again'
64 ' in order to rescan repositories') % repo_name,
64 ' in order to rescan repositories') % repo_name,
65 category='error')
65 category='error')
66
66
67 return redirect(url('home'))
67 return redirect(url('home'))
68
68
69 c.users_array = repo_model.get_users_js()
69 c.users_array = repo_model.get_users_js()
70 c.users_groups_array = repo_model.get_users_groups_js()
70 c.users_groups_array = repo_model.get_users_groups_js()
71
71
72 defaults = c.repo_info.get_dict()
72 defaults = c.repo_info.get_dict()
73
73
74 #fill owner
74 #fill owner
75 if c.repo_info.user:
75 if c.repo_info.user:
76 defaults.update({'user':c.repo_info.user.username})
76 defaults.update({'user':c.repo_info.user.username})
77 else:
77 else:
78 replacement_user = self.sa.query(User)\
78 replacement_user = self.sa.query(User)\
79 .filter(User.admin == True).first().username
79 .filter(User.admin == True).first().username
80 defaults.update({'user':replacement_user})
80 defaults.update({'user':replacement_user})
81
81
82 #fill repository users
82 #fill repository users
83 for p in c.repo_info.repo_to_perm:
83 for p in c.repo_info.repo_to_perm:
84 defaults.update({'u_perm_%s' % p.user.username:
84 defaults.update({'u_perm_%s' % p.user.username:
85 p.permission.permission_name})
85 p.permission.permission_name})
86
86
87 #fill repository groups
87 #fill repository groups
88 for p in c.repo_info.users_group_to_perm:
88 for p in c.repo_info.users_group_to_perm:
89 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
89 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
90 p.permission.permission_name})
90 p.permission.permission_name})
91
91
92 return formencode.htmlfill.render(
92 return formencode.htmlfill.render(
93 render('settings/repo_settings.html'),
93 render('settings/repo_settings.html'),
94 defaults=defaults,
94 defaults=defaults,
95 encoding="UTF-8",
95 encoding="UTF-8",
96 force_defaults=False
96 force_defaults=False
97 )
97 )
98
98
99 @HasRepoPermissionAllDecorator('repository.admin')
99 @HasRepoPermissionAllDecorator('repository.admin')
100 def update(self, repo_name):
100 def update(self, repo_name):
101 repo_model = RepoModel()
101 repo_model = RepoModel()
102 changed_name = repo_name
102 changed_name = repo_name
103 _form = RepoSettingsForm(edit=True, old_data={'repo_name':repo_name})()
103 _form = RepoSettingsForm(edit=True, old_data={'repo_name':repo_name})()
104 try:
104 try:
105 form_result = _form.to_python(dict(request.POST))
105 form_result = _form.to_python(dict(request.POST))
106 repo_model.update(repo_name, form_result)
106 repo_model.update(repo_name, form_result)
107 invalidate_cache('get_repo_cached_%s' % repo_name)
107 invalidate_cache('get_repo_cached_%s' % repo_name)
108 h.flash(_('Repository %s updated successfully' % repo_name),
108 h.flash(_('Repository %s updated successfully' % repo_name),
109 category='success')
109 category='success')
110 changed_name = form_result['repo_name']
110 changed_name = form_result['repo_name']
111 action_logger(self.rhodecode_user, 'user_updated_repo',
111 action_logger(self.rhodecode_user, 'user_updated_repo',
112 changed_name, '', self.sa)
112 changed_name, '', self.sa)
113 except formencode.Invalid, errors:
113 except formencode.Invalid, errors:
114 c.repo_info = repo_model.get_by_repo_name(repo_name)
114 c.repo_info = repo_model.get_by_repo_name(repo_name)
115 c.users_array = repo_model.get_users_js()
115 c.users_array = repo_model.get_users_js()
116 errors.value.update({'user':c.repo_info.user.username})
116 errors.value.update({'user':c.repo_info.user.username})
117 return formencode.htmlfill.render(
117 return formencode.htmlfill.render(
118 render('settings/repo_settings.html'),
118 render('settings/repo_settings.html'),
119 defaults=errors.value,
119 defaults=errors.value,
120 errors=errors.error_dict or {},
120 errors=errors.error_dict or {},
121 prefix_error=False,
121 prefix_error=False,
122 encoding="UTF-8")
122 encoding="UTF-8")
123 except Exception:
123 except Exception:
124 log.error(traceback.format_exc())
124 log.error(traceback.format_exc())
125 h.flash(_('error occurred during update of repository %s') \
125 h.flash(_('error occurred during update of repository %s') \
126 % repo_name, category='error')
126 % repo_name, category='error')
127
127
128 return redirect(url('repo_settings_home', repo_name=changed_name))
128 return redirect(url('repo_settings_home', repo_name=changed_name))
129
129
130
130
131 @HasRepoPermissionAllDecorator('repository.admin')
131 @HasRepoPermissionAllDecorator('repository.admin')
132 def delete(self, repo_name):
132 def delete(self, repo_name):
133 """DELETE /repos/repo_name: Delete an existing item"""
133 """DELETE /repos/repo_name: Delete an existing item"""
134 # Forms posted to this method should contain a hidden field:
134 # Forms posted to this method should contain a hidden field:
135 # <input type="hidden" name="_method" value="DELETE" />
135 # <input type="hidden" name="_method" value="DELETE" />
136 # Or using helpers:
136 # Or using helpers:
137 # h.form(url('repo_settings_delete', repo_name=ID),
137 # h.form(url('repo_settings_delete', repo_name=ID),
138 # method='delete')
138 # method='delete')
139 # url('repo_settings_delete', repo_name=ID)
139 # url('repo_settings_delete', repo_name=ID)
140
140
141 repo_model = RepoModel()
141 repo_model = RepoModel()
142 repo = repo_model.get_by_repo_name(repo_name)
142 repo = repo_model.get_by_repo_name(repo_name)
143 if not repo:
143 if not repo:
144 h.flash(_('%s repository is not mapped to db perhaps'
144 h.flash(_('%s repository is not mapped to db perhaps'
145 ' it was moved or renamed from the filesystem'
145 ' it was moved or renamed from the filesystem'
146 ' please run the application again'
146 ' please run the application again'
147 ' in order to rescan repositories') % repo_name,
147 ' in order to rescan repositories') % repo_name,
148 category='error')
148 category='error')
149
149
150 return redirect(url('home'))
150 return redirect(url('home'))
151 try:
151 try:
152 action_logger(self.rhodecode_user, 'user_deleted_repo',
152 action_logger(self.rhodecode_user, 'user_deleted_repo',
153 repo_name, '', self.sa)
153 repo_name, '', self.sa)
154 repo_model.delete(repo)
154 repo_model.delete(repo)
155 invalidate_cache('get_repo_cached_%s' % repo_name)
155 invalidate_cache('get_repo_cached_%s' % repo_name)
156 h.flash(_('deleted repository %s') % repo_name, category='success')
156 h.flash(_('deleted repository %s') % repo_name, category='success')
157 except Exception:
157 except Exception:
158 h.flash(_('An error occurred during deletion of %s') % repo_name,
158 h.flash(_('An error occurred during deletion of %s') % repo_name,
159 category='error')
159 category='error')
160
160
161 return redirect(url('home'))
161 return redirect(url('home'))
162
162
163 @NotAnonymous()
163 @NotAnonymous()
164 @HasRepoPermissionAllDecorator('repository.read')
164 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
165 'repository.admin')
165 def fork(self, repo_name):
166 def fork(self, repo_name):
166 repo_model = RepoModel()
167 repo_model = RepoModel()
167 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
168 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
168 if not repo:
169 if not repo:
169 h.flash(_('%s repository is not mapped to db perhaps'
170 h.flash(_('%s repository is not mapped to db perhaps'
170 ' it was created or renamed from the file system'
171 ' it was created or renamed from the file system'
171 ' please run the application again'
172 ' please run the application again'
172 ' in order to rescan repositories') % repo_name,
173 ' in order to rescan repositories') % repo_name,
173 category='error')
174 category='error')
174
175
175 return redirect(url('home'))
176 return redirect(url('home'))
176
177
177 return render('settings/repo_fork.html')
178 return render('settings/repo_fork.html')
178
179
179 @NotAnonymous()
180 @NotAnonymous()
180 @HasRepoPermissionAllDecorator('repository.read')
181 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
182 'repository.admin')
181 def fork_create(self, repo_name):
183 def fork_create(self, repo_name):
182 repo_model = RepoModel()
184 repo_model = RepoModel()
183 c.repo_info = repo_model.get_by_repo_name(repo_name)
185 c.repo_info = repo_model.get_by_repo_name(repo_name)
184 _form = RepoForkForm(old_data={'repo_type':c.repo_info.repo_type})()
186 _form = RepoForkForm(old_data={'repo_type':c.repo_info.repo_type})()
185 form_result = {}
187 form_result = {}
186 try:
188 try:
187 form_result = _form.to_python(dict(request.POST))
189 form_result = _form.to_python(dict(request.POST))
188 form_result.update({'repo_name':repo_name})
190 form_result.update({'repo_name':repo_name})
189 repo_model.create_fork(form_result, c.rhodecode_user)
191 repo_model.create_fork(form_result, c.rhodecode_user)
190 h.flash(_('forked %s repository as %s') \
192 h.flash(_('forked %s repository as %s') \
191 % (repo_name, form_result['fork_name']),
193 % (repo_name, form_result['fork_name']),
192 category='success')
194 category='success')
193 action_logger(self.rhodecode_user,
195 action_logger(self.rhodecode_user,
194 'user_forked_repo:%s' % form_result['fork_name'],
196 'user_forked_repo:%s' % form_result['fork_name'],
195 repo_name, '', self.sa)
197 repo_name, '', self.sa)
196 except formencode.Invalid, errors:
198 except formencode.Invalid, errors:
197 c.new_repo = errors.value['fork_name']
199 c.new_repo = errors.value['fork_name']
198 r = render('settings/repo_fork.html')
200 r = render('settings/repo_fork.html')
199
201
200 return formencode.htmlfill.render(
202 return formencode.htmlfill.render(
201 r,
203 r,
202 defaults=errors.value,
204 defaults=errors.value,
203 errors=errors.error_dict or {},
205 errors=errors.error_dict or {},
204 prefix_error=False,
206 prefix_error=False,
205 encoding="UTF-8")
207 encoding="UTF-8")
206 return redirect(url('home'))
208 return redirect(url('home'))
General Comments 0
You need to be logged in to leave comments. Login now