Show More
@@ -54,7 +54,6 b' def make_map(config):' | |||||
54 | :param match_dict: |
|
54 | :param match_dict: | |
55 | """ |
|
55 | """ | |
56 | repos_group_name = match_dict.get('group_name') |
|
56 | repos_group_name = match_dict.get('group_name') | |
57 |
|
||||
58 | return is_valid_repos_group(repos_group_name, config['base_path']) |
|
57 | return is_valid_repos_group(repos_group_name, config['base_path']) | |
59 |
|
58 | |||
60 | def check_int(environ, match_dict): |
|
59 | def check_int(environ, match_dict): | |
@@ -158,33 +157,33 b' def make_map(config):' | |||||
158 | action="new", conditions=dict(method=["GET"])) |
|
157 | action="new", conditions=dict(method=["GET"])) | |
159 | m.connect("formatted_new_repos_group", "/repos_groups/new.{format}", |
|
158 | m.connect("formatted_new_repos_group", "/repos_groups/new.{format}", | |
160 | action="new", conditions=dict(method=["GET"])) |
|
159 | action="new", conditions=dict(method=["GET"])) | |
161 |
m.connect("update_repos_group", "/repos_groups/{ |
|
160 | m.connect("update_repos_group", "/repos_groups/{group_name:.*?}", | |
162 | action="update", conditions=dict(method=["PUT"], |
|
161 | action="update", conditions=dict(method=["PUT"], | |
163 |
function=check_ |
|
162 | function=check_group)) | |
164 |
m.connect("delete_repos_group", "/repos_groups/{ |
|
163 | m.connect("delete_repos_group", "/repos_groups/{group_name:.*?}", | |
165 | action="delete", conditions=dict(method=["DELETE"], |
|
164 | action="delete", conditions=dict(method=["DELETE"], | |
166 |
function=check_ |
|
165 | function=check_group)) | |
167 |
m.connect("edit_repos_group", "/repos_groups/{ |
|
166 | m.connect("edit_repos_group", "/repos_groups/{group_name:.*?}/edit", | |
168 | action="edit", conditions=dict(method=["GET"],)) |
|
167 | action="edit", conditions=dict(method=["GET"],)) | |
169 | m.connect("formatted_edit_repos_group", |
|
168 | m.connect("formatted_edit_repos_group", | |
170 |
"/repos_groups/{ |
|
169 | "/repos_groups/{group_name:.*?}.{format}/edit", | |
171 | action="edit", conditions=dict(method=["GET"], |
|
170 | action="edit", conditions=dict(method=["GET"], | |
172 |
function=check_ |
|
171 | function=check_group)) | |
173 |
m.connect("repos_group", "/repos_groups/{ |
|
172 | m.connect("repos_group", "/repos_groups/{group_name:.*?}", | |
174 | action="show", conditions=dict(method=["GET"], |
|
173 | action="show", conditions=dict(method=["GET"], | |
175 |
function=check_ |
|
174 | function=check_group)) | |
176 |
m.connect("formatted_repos_group", "/repos_groups/{ |
|
175 | m.connect("formatted_repos_group", "/repos_groups/{group_name:.*?}.{format}", | |
177 | action="show", conditions=dict(method=["GET"], |
|
176 | action="show", conditions=dict(method=["GET"], | |
178 |
function=check_ |
|
177 | function=check_group)) | |
179 | # ajax delete repos group perm user |
|
178 | # ajax delete repos group perm user | |
180 | m.connect('delete_repos_group_user_perm', |
|
179 | m.connect('delete_repos_group_user_perm', | |
181 | "/delete_repos_group_user_perm/{group_name:.*}", |
|
180 | "/delete_repos_group_user_perm/{group_name:.*?}", | |
182 | action="delete_repos_group_user_perm", |
|
181 | action="delete_repos_group_user_perm", | |
183 | conditions=dict(method=["DELETE"], function=check_group)) |
|
182 | conditions=dict(method=["DELETE"], function=check_group)) | |
184 |
|
183 | |||
185 | # ajax delete repos group perm users_group |
|
184 | # ajax delete repos group perm users_group | |
186 | m.connect('delete_repos_group_users_group_perm', |
|
185 | m.connect('delete_repos_group_users_group_perm', | |
187 | "/delete_repos_group_users_group_perm/{group_name:.*}", |
|
186 | "/delete_repos_group_users_group_perm/{group_name:.*?}", | |
188 | action="delete_repos_group_users_group_perm", |
|
187 | action="delete_repos_group_users_group_perm", | |
189 | conditions=dict(method=["DELETE"], function=check_group)) |
|
188 | conditions=dict(method=["DELETE"], function=check_group)) | |
190 |
|
189 |
@@ -30,7 +30,7 b' import formencode' | |||||
30 | from formencode import htmlfill |
|
30 | from formencode import htmlfill | |
31 |
|
31 | |||
32 | from pylons import request, tmpl_context as c, url |
|
32 | from pylons import request, tmpl_context as c, url | |
33 | from pylons.controllers.util import redirect |
|
33 | from pylons.controllers.util import abort, redirect | |
34 | from pylons.i18n.translation import _ |
|
34 | from pylons.i18n.translation import _ | |
35 |
|
35 | |||
36 | from sqlalchemy.exc import IntegrityError |
|
36 | from sqlalchemy.exc import IntegrityError | |
@@ -39,7 +39,8 b' import rhodecode' | |||||
39 | from rhodecode.lib import helpers as h |
|
39 | from rhodecode.lib import helpers as h | |
40 | from rhodecode.lib.ext_json import json |
|
40 | from rhodecode.lib.ext_json import json | |
41 | from rhodecode.lib.auth import LoginRequired, HasPermissionAnyDecorator,\ |
|
41 | from rhodecode.lib.auth import LoginRequired, HasPermissionAnyDecorator,\ | |
42 | HasReposGroupPermissionAnyDecorator |
|
42 | HasReposGroupPermissionAnyDecorator, HasReposGroupPermissionAll,\ | |
|
43 | HasPermissionAll | |||
43 | from rhodecode.lib.base import BaseController, render |
|
44 | from rhodecode.lib.base import BaseController, render | |
44 | from rhodecode.model.db import RepoGroup, Repository |
|
45 | from rhodecode.model.db import RepoGroup, Repository | |
45 | from rhodecode.model.repos_group import ReposGroupModel |
|
46 | from rhodecode.model.repos_group import ReposGroupModel | |
@@ -47,8 +48,9 b' from rhodecode.model.forms import ReposG' | |||||
47 | from rhodecode.model.meta import Session |
|
48 | from rhodecode.model.meta import Session | |
48 | from rhodecode.model.repo import RepoModel |
|
49 | from rhodecode.model.repo import RepoModel | |
49 | from webob.exc import HTTPInternalServerError, HTTPNotFound |
|
50 | from webob.exc import HTTPInternalServerError, HTTPNotFound | |
50 | from rhodecode.lib.utils2 import str2bool |
|
51 | from rhodecode.lib.utils2 import str2bool, safe_int | |
51 | from sqlalchemy.sql.expression import func |
|
52 | from sqlalchemy.sql.expression import func | |
|
53 | from rhodecode.model.scm import GroupList | |||
52 |
|
54 | |||
53 | log = logging.getLogger(__name__) |
|
55 | log = logging.getLogger(__name__) | |
54 |
|
56 | |||
@@ -63,10 +65,21 b' class ReposGroupsController(BaseControll' | |||||
63 | def __before__(self): |
|
65 | def __before__(self): | |
64 | super(ReposGroupsController, self).__before__() |
|
66 | super(ReposGroupsController, self).__before__() | |
65 |
|
67 | |||
66 | def __load_defaults(self): |
|
68 | def __load_defaults(self, allow_empty_group=False, exclude_group_ids=[]): | |
67 | c.repo_groups = RepoGroup.groups_choices() |
|
69 | if HasPermissionAll('hg.admin')('group edit'): | |
|
70 | #we're global admin, we're ok and we can create TOP level groups | |||
|
71 | allow_empty_group = True | |||
|
72 | ||||
|
73 | #override the choices for this form, we need to filter choices | |||
|
74 | #and display only those we have ADMIN right | |||
|
75 | groups_with_admin_rights = GroupList(RepoGroup.query().all(), | |||
|
76 | perm_set=['group.admin']) | |||
|
77 | c.repo_groups = RepoGroup.groups_choices(groups=groups_with_admin_rights, | |||
|
78 | show_empty_group=allow_empty_group) | |||
|
79 | # exclude filtered ids | |||
|
80 | c.repo_groups = filter(lambda x: x[0] not in exclude_group_ids, | |||
|
81 | c.repo_groups) | |||
68 | c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) |
|
82 | c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) | |
69 |
|
||||
70 | repo_model = RepoModel() |
|
83 | repo_model = RepoModel() | |
71 | c.users_array = repo_model.get_users_js() |
|
84 | c.users_array = repo_model.get_users_js() | |
72 | c.users_groups_array = repo_model.get_users_groups_js() |
|
85 | c.users_groups_array = repo_model.get_users_groups_js() | |
@@ -77,7 +90,6 b' class ReposGroupsController(BaseControll' | |||||
77 |
|
90 | |||
78 | :param group_id: |
|
91 | :param group_id: | |
79 | """ |
|
92 | """ | |
80 | self.__load_defaults() |
|
|||
81 | repo_group = RepoGroup.get_or_404(group_id) |
|
93 | repo_group = RepoGroup.get_or_404(group_id) | |
82 | data = repo_group.get_dict() |
|
94 | data = repo_group.get_dict() | |
83 | data['group_name'] = repo_group.name |
|
95 | data['group_name'] = repo_group.name | |
@@ -94,34 +106,37 b' class ReposGroupsController(BaseControll' | |||||
94 |
|
106 | |||
95 | return data |
|
107 | return data | |
96 |
|
108 | |||
97 | @HasPermissionAnyDecorator('hg.admin') |
|
|||
98 | def index(self, format='html'): |
|
109 | def index(self, format='html'): | |
99 | """GET /repos_groups: All items in the collection""" |
|
110 | """GET /repos_groups: All items in the collection""" | |
100 | # url('repos_groups') |
|
111 | # url('repos_groups') | |
|
112 | group_iter = GroupList(RepoGroup.query().all(), perm_set=['group.admin']) | |||
101 | sk = lambda g: g.parents[0].group_name if g.parents else g.group_name |
|
113 | sk = lambda g: g.parents[0].group_name if g.parents else g.group_name | |
102 |
c.groups = sorted( |
|
114 | c.groups = sorted(group_iter, key=sk) | |
103 | return render('admin/repos_groups/repos_groups_show.html') |
|
115 | return render('admin/repos_groups/repos_groups_show.html') | |
104 |
|
116 | |||
105 | @HasPermissionAnyDecorator('hg.admin') |
|
|||
106 | def create(self): |
|
117 | def create(self): | |
107 | """POST /repos_groups: Create a new item""" |
|
118 | """POST /repos_groups: Create a new item""" | |
108 | # url('repos_groups') |
|
119 | # url('repos_groups') | |
|
120 | ||||
109 | self.__load_defaults() |
|
121 | self.__load_defaults() | |
110 | repos_group_form = ReposGroupForm(available_groups = |
|
122 | ||
111 | c.repo_groups_choices)() |
|
123 | # permissions for can create group based on parent_id are checked | |
|
124 | # here in the Form | |||
|
125 | repos_group_form = ReposGroupForm(available_groups= | |||
|
126 | map(lambda k: unicode(k[0]), c.repo_groups))() | |||
112 | try: |
|
127 | try: | |
113 | form_result = repos_group_form.to_python(dict(request.POST)) |
|
128 | form_result = repos_group_form.to_python(dict(request.POST)) | |
114 | ReposGroupModel().create( |
|
129 | ReposGroupModel().create( | |
115 | group_name=form_result['group_name'], |
|
130 | group_name=form_result['group_name'], | |
116 | group_description=form_result['group_description'], |
|
131 | group_description=form_result['group_description'], | |
117 | parent=form_result['group_parent_id'] |
|
132 | parent=form_result['group_parent_id'], | |
|
133 | owner=self.rhodecode_user.user_id | |||
118 | ) |
|
134 | ) | |
119 | Session().commit() |
|
135 | Session().commit() | |
120 | h.flash(_('created repos group %s') \ |
|
136 | h.flash(_('created repos group %s') \ | |
121 | % form_result['group_name'], category='success') |
|
137 | % form_result['group_name'], category='success') | |
122 | #TODO: in futureaction_logger(, '', '', '', self.sa) |
|
138 | #TODO: in futureaction_logger(, '', '', '', self.sa) | |
123 | except formencode.Invalid, errors: |
|
139 | except formencode.Invalid, errors: | |
124 |
|
||||
125 | return htmlfill.render( |
|
140 | return htmlfill.render( | |
126 | render('admin/repos_groups/repos_groups_add.html'), |
|
141 | render('admin/repos_groups/repos_groups_add.html'), | |
127 | defaults=errors.value, |
|
142 | defaults=errors.value, | |
@@ -132,40 +147,65 b' class ReposGroupsController(BaseControll' | |||||
132 | log.error(traceback.format_exc()) |
|
147 | log.error(traceback.format_exc()) | |
133 | h.flash(_('error occurred during creation of repos group %s') \ |
|
148 | h.flash(_('error occurred during creation of repos group %s') \ | |
134 | % request.POST.get('group_name'), category='error') |
|
149 | % request.POST.get('group_name'), category='error') | |
|
150 | parent_group_id = form_result['group_parent_id'] | |||
|
151 | #TODO: maybe we should get back to the main view, not the admin one | |||
|
152 | return redirect(url('repos_groups', parent_group=parent_group_id)) | |||
135 |
|
153 | |||
136 | return redirect(url('repos_groups')) |
|
|||
137 |
|
||||
138 | @HasPermissionAnyDecorator('hg.admin') |
|
|||
139 | def new(self, format='html'): |
|
154 | def new(self, format='html'): | |
140 | """GET /repos_groups/new: Form to create a new item""" |
|
155 | """GET /repos_groups/new: Form to create a new item""" | |
141 | # url('new_repos_group') |
|
156 | # url('new_repos_group') | |
|
157 | if HasPermissionAll('hg.admin')('group create'): | |||
|
158 | #we're global admin, we're ok and we can create TOP level groups | |||
|
159 | pass | |||
|
160 | else: | |||
|
161 | # we pass in parent group into creation form, thus we know | |||
|
162 | # what would be the group, we can check perms here ! | |||
|
163 | group_id = safe_int(request.GET.get('parent_group')) | |||
|
164 | group = RepoGroup.get(group_id) if group_id else None | |||
|
165 | group_name = group.group_name if group else None | |||
|
166 | if HasReposGroupPermissionAll('group.admin')(group_name, 'group create'): | |||
|
167 | pass | |||
|
168 | else: | |||
|
169 | return abort(403) | |||
|
170 | ||||
142 | self.__load_defaults() |
|
171 | self.__load_defaults() | |
143 | return render('admin/repos_groups/repos_groups_add.html') |
|
172 | return render('admin/repos_groups/repos_groups_add.html') | |
144 |
|
173 | |||
145 |
@HasPermissionAnyDecorator(' |
|
174 | @HasReposGroupPermissionAnyDecorator('group.admin') | |
146 |
def update(self, |
|
175 | def update(self, group_name): | |
147 |
"""PUT /repos_groups/ |
|
176 | """PUT /repos_groups/group_name: Update an existing item""" | |
148 | # Forms posted to this method should contain a hidden field: |
|
177 | # Forms posted to this method should contain a hidden field: | |
149 | # <input type="hidden" name="_method" value="PUT" /> |
|
178 | # <input type="hidden" name="_method" value="PUT" /> | |
150 | # Or using helpers: |
|
179 | # Or using helpers: | |
151 |
# h.form(url('repos_group', |
|
180 | # h.form(url('repos_group', group_name=GROUP_NAME), | |
152 | # method='put') |
|
181 | # method='put') | |
153 |
# url('repos_group', |
|
182 | # url('repos_group', group_name=GROUP_NAME) | |
154 |
|
183 | |||
155 | self.__load_defaults() |
|
184 | c.repos_group = ReposGroupModel()._get_repos_group(group_name) | |
156 | c.repos_group = RepoGroup.get(id) |
|
185 | if HasPermissionAll('hg.admin')('group edit'): | |
|
186 | #we're global admin, we're ok and we can create TOP level groups | |||
|
187 | allow_empty_group = True | |||
|
188 | elif not c.repos_group.parent_group: | |||
|
189 | allow_empty_group = True | |||
|
190 | else: | |||
|
191 | allow_empty_group = False | |||
|
192 | self.__load_defaults(allow_empty_group=allow_empty_group, | |||
|
193 | exclude_group_ids=[c.repos_group.group_id]) | |||
157 |
|
194 | |||
158 | repos_group_form = ReposGroupForm( |
|
195 | repos_group_form = ReposGroupForm( | |
159 | edit=True, |
|
196 | edit=True, | |
160 | old_data=c.repos_group.get_dict(), |
|
197 | old_data=c.repos_group.get_dict(), | |
161 | available_groups=c.repo_groups_choices |
|
198 | available_groups=c.repo_groups_choices, | |
|
199 | can_create_in_root=allow_empty_group, | |||
162 | )() |
|
200 | )() | |
163 | try: |
|
201 | try: | |
164 | form_result = repos_group_form.to_python(dict(request.POST)) |
|
202 | form_result = repos_group_form.to_python(dict(request.POST)) | |
165 |
ReposGroupModel().update( |
|
203 | new_gr = ReposGroupModel().update(group_name, form_result) | |
166 | Session().commit() |
|
204 | Session().commit() | |
167 | h.flash(_('updated repos group %s') \ |
|
205 | h.flash(_('updated repos group %s') \ | |
168 | % form_result['group_name'], category='success') |
|
206 | % form_result['group_name'], category='success') | |
|
207 | # we now have new name ! | |||
|
208 | group_name = new_gr.group_name | |||
169 | #TODO: in future action_logger(, '', '', '', self.sa) |
|
209 | #TODO: in future action_logger(, '', '', '', self.sa) | |
170 | except formencode.Invalid, errors: |
|
210 | except formencode.Invalid, errors: | |
171 |
|
211 | |||
@@ -180,19 +220,19 b' class ReposGroupsController(BaseControll' | |||||
180 | h.flash(_('error occurred during update of repos group %s') \ |
|
220 | h.flash(_('error occurred during update of repos group %s') \ | |
181 | % request.POST.get('group_name'), category='error') |
|
221 | % request.POST.get('group_name'), category='error') | |
182 |
|
222 | |||
183 |
return redirect(url('edit_repos_group', |
|
223 | return redirect(url('edit_repos_group', group_name=group_name)) | |
184 |
|
224 | |||
185 |
@HasPermissionAnyDecorator(' |
|
225 | @HasReposGroupPermissionAnyDecorator('group.admin') | |
186 |
def delete(self, |
|
226 | def delete(self, group_name): | |
187 |
"""DELETE /repos_groups/ |
|
227 | """DELETE /repos_groups/group_name: Delete an existing item""" | |
188 | # Forms posted to this method should contain a hidden field: |
|
228 | # Forms posted to this method should contain a hidden field: | |
189 | # <input type="hidden" name="_method" value="DELETE" /> |
|
229 | # <input type="hidden" name="_method" value="DELETE" /> | |
190 | # Or using helpers: |
|
230 | # Or using helpers: | |
191 |
# h.form(url('repos_group', |
|
231 | # h.form(url('repos_group', group_name=GROUP_NAME), | |
192 | # method='delete') |
|
232 | # method='delete') | |
193 |
# url('repos_group', |
|
233 | # url('repos_group', group_name=GROUP_NAME) | |
194 |
|
234 | |||
195 | gr = RepoGroup.get(id) |
|
235 | gr = c.repos_group = ReposGroupModel()._get_repos_group(group_name) | |
196 | repos = gr.repositories.all() |
|
236 | repos = gr.repositories.all() | |
197 | if repos: |
|
237 | if repos: | |
198 | h.flash(_('This group contains %s repositores and cannot be ' |
|
238 | h.flash(_('This group contains %s repositores and cannot be ' | |
@@ -201,7 +241,7 b' class ReposGroupsController(BaseControll' | |||||
201 | return redirect(url('repos_groups')) |
|
241 | return redirect(url('repos_groups')) | |
202 |
|
242 | |||
203 | try: |
|
243 | try: | |
204 |
ReposGroupModel().delete( |
|
244 | ReposGroupModel().delete(group_name) | |
205 | Session().commit() |
|
245 | Session().commit() | |
206 | h.flash(_('removed repos group %s') % gr.group_name, |
|
246 | h.flash(_('removed repos group %s') % gr.group_name, | |
207 | category='success') |
|
247 | category='success') | |
@@ -279,11 +319,11 b' class ReposGroupsController(BaseControll' | |||||
279 |
|
319 | |||
280 | @HasReposGroupPermissionAnyDecorator('group.read', 'group.write', |
|
320 | @HasReposGroupPermissionAnyDecorator('group.read', 'group.write', | |
281 | 'group.admin') |
|
321 | 'group.admin') | |
282 |
def show(self, |
|
322 | def show(self, group_name, format='html'): | |
283 |
"""GET /repos_groups/ |
|
323 | """GET /repos_groups/group_name: Show a specific item""" | |
284 |
# url('repos_group', |
|
324 | # url('repos_group', group_name=GROUP_NAME) | |
285 |
|
325 | |||
286 | c.group = RepoGroup.get_or_404(id) |
|
326 | c.group = c.repos_group = ReposGroupModel()._get_repos_group(group_name) | |
287 | c.group_repos = c.group.repositories.all() |
|
327 | c.group_repos = c.group.repositories.all() | |
288 |
|
328 | |||
289 | #overwrite our cached list with current filter |
|
329 | #overwrite our cached list with current filter | |
@@ -291,7 +331,7 b' class ReposGroupsController(BaseControll' | |||||
291 | c.repo_cnt = 0 |
|
331 | c.repo_cnt = 0 | |
292 |
|
332 | |||
293 | groups = RepoGroup.query().order_by(RepoGroup.group_name)\ |
|
333 | groups = RepoGroup.query().order_by(RepoGroup.group_name)\ | |
294 | .filter(RepoGroup.group_parent_id == id).all() |
|
334 | .filter(RepoGroup.group_parent_id == c.group.group_id).all() | |
295 | c.groups = self.scm_model.get_repos_groups(groups) |
|
335 | c.groups = self.scm_model.get_repos_groups(groups) | |
296 |
|
336 | |||
297 | if c.visual.lightweight_dashboard is False: |
|
337 | if c.visual.lightweight_dashboard is False: | |
@@ -299,7 +339,7 b' class ReposGroupsController(BaseControll' | |||||
299 | ## lightweight version of dashboard |
|
339 | ## lightweight version of dashboard | |
300 | else: |
|
340 | else: | |
301 | c.repos_list = Repository.query()\ |
|
341 | c.repos_list = Repository.query()\ | |
302 | .filter(Repository.group_id == id)\ |
|
342 | .filter(Repository.group_id == c.group.group_id)\ | |
303 | .order_by(func.lower(Repository.repo_name))\ |
|
343 | .order_by(func.lower(Repository.repo_name))\ | |
304 | .all() |
|
344 | .all() | |
305 |
|
345 | |||
@@ -310,17 +350,25 b' class ReposGroupsController(BaseControll' | |||||
310 |
|
350 | |||
311 | return render('admin/repos_groups/repos_groups.html') |
|
351 | return render('admin/repos_groups/repos_groups.html') | |
312 |
|
352 | |||
313 |
@HasPermissionAnyDecorator(' |
|
353 | @HasReposGroupPermissionAnyDecorator('group.admin') | |
314 |
def edit(self, |
|
354 | def edit(self, group_name, format='html'): | |
315 |
"""GET /repos_groups/ |
|
355 | """GET /repos_groups/group_name/edit: Form to edit an existing item""" | |
316 |
# url('edit_repos_group', |
|
356 | # url('edit_repos_group', group_name=GROUP_NAME) | |
317 |
|
357 | |||
318 |
c.repos_group = ReposGroupModel()._get_repos_group( |
|
358 | c.repos_group = ReposGroupModel()._get_repos_group(group_name) | |
319 | defaults = self.__load_data(c.repos_group.group_id) |
|
359 | #we can only allow moving empty group if it's already a top-level | |
|
360 | #group, ie has no parents, or we're admin | |||
|
361 | if HasPermissionAll('hg.admin')('group edit'): | |||
|
362 | #we're global admin, we're ok and we can create TOP level groups | |||
|
363 | allow_empty_group = True | |||
|
364 | elif not c.repos_group.parent_group: | |||
|
365 | allow_empty_group = True | |||
|
366 | else: | |||
|
367 | allow_empty_group = False | |||
320 |
|
368 | |||
321 | # we need to exclude this group from the group list for editing |
|
369 | self.__load_defaults(allow_empty_group=allow_empty_group, | |
322 | c.repo_groups = filter(lambda x: x[0] != c.repos_group.group_id, |
|
370 | exclude_group_ids=[c.repos_group.group_id]) | |
323 | c.repo_groups) |
|
371 | defaults = self.__load_data(c.repos_group.group_id) | |
324 |
|
372 | |||
325 | return htmlfill.render( |
|
373 | return htmlfill.render( | |
326 | render('admin/repos_groups/repos_groups_edit.html'), |
|
374 | render('admin/repos_groups/repos_groups_edit.html'), |
@@ -659,7 +659,6 b' class HasRepoPermissionAnyDecorator(Perm' | |||||
659 |
|
659 | |||
660 | def check_permissions(self): |
|
660 | def check_permissions(self): | |
661 | repo_name = get_repo_slug(request) |
|
661 | repo_name = get_repo_slug(request) | |
662 |
|
||||
663 | try: |
|
662 | try: | |
664 | user_perms = set([self.user_perms['repositories'][repo_name]]) |
|
663 | user_perms = set([self.user_perms['repositories'][repo_name]]) | |
665 | except KeyError: |
|
664 | except KeyError: | |
@@ -682,6 +681,7 b' class HasReposGroupPermissionAllDecorato' | |||||
682 | user_perms = set([self.user_perms['repositories_groups'][group_name]]) |
|
681 | user_perms = set([self.user_perms['repositories_groups'][group_name]]) | |
683 | except KeyError: |
|
682 | except KeyError: | |
684 | return False |
|
683 | return False | |
|
684 | ||||
685 | if self.required_perms.issubset(user_perms): |
|
685 | if self.required_perms.issubset(user_perms): | |
686 | return True |
|
686 | return True | |
687 | return False |
|
687 | return False | |
@@ -695,11 +695,11 b' class HasReposGroupPermissionAnyDecorato' | |||||
695 |
|
695 | |||
696 | def check_permissions(self): |
|
696 | def check_permissions(self): | |
697 | group_name = get_repos_group_slug(request) |
|
697 | group_name = get_repos_group_slug(request) | |
698 |
|
||||
699 | try: |
|
698 | try: | |
700 | user_perms = set([self.user_perms['repositories_groups'][group_name]]) |
|
699 | user_perms = set([self.user_perms['repositories_groups'][group_name]]) | |
701 | except KeyError: |
|
700 | except KeyError: | |
702 | return False |
|
701 | return False | |
|
702 | ||||
703 | if self.required_perms.intersection(user_perms): |
|
703 | if self.required_perms.intersection(user_perms): | |
704 | return True |
|
704 | return True | |
705 | return False |
|
705 | return False |
@@ -741,7 +741,8 b' def action_parser(user_log, feed=False, ' | |||||
741 | # PERMS |
|
741 | # PERMS | |
742 | #============================================================================== |
|
742 | #============================================================================== | |
743 | from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \ |
|
743 | from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \ | |
744 | HasRepoPermissionAny, HasRepoPermissionAll |
|
744 | HasRepoPermissionAny, HasRepoPermissionAll, HasReposGroupPermissionAll, \ | |
|
745 | HasReposGroupPermissionAny | |||
745 |
|
746 | |||
746 |
|
747 | |||
747 | #============================================================================== |
|
748 | #============================================================================== |
@@ -1172,15 +1172,18 b' class RepoGroup(Base, BaseModel):' | |||||
1172 | self.group_name) |
|
1172 | self.group_name) | |
1173 |
|
1173 | |||
1174 | @classmethod |
|
1174 | @classmethod | |
1175 | def groups_choices(cls, check_perms=False): |
|
1175 | def groups_choices(cls, groups=None, check_perms=False, show_empty_group=True): | |
1176 | from webhelpers.html import literal as _literal |
|
1176 | from webhelpers.html import literal as _literal | |
1177 | from rhodecode.model.scm import ScmModel |
|
1177 | from rhodecode.model.scm import ScmModel | |
1178 | groups = cls.query().all() |
|
1178 | if not groups: | |
|
1179 | groups = cls.query().all() | |||
1179 | if check_perms: |
|
1180 | if check_perms: | |
1180 | #filter group user have access to, it's done |
|
1181 | #filter group user have access to, it's done | |
1181 | #magically inside ScmModel based on current user |
|
1182 | #magically inside ScmModel based on current user | |
1182 | groups = ScmModel().get_repos_groups(groups) |
|
1183 | groups = ScmModel().get_repos_groups(groups) | |
1183 |
repo_groups = [ |
|
1184 | repo_groups = [] | |
|
1185 | if show_empty_group: | |||
|
1186 | repo_groups = [('-1', '-- no parent --')] | |||
1184 | sep = ' » ' |
|
1187 | sep = ' » ' | |
1185 | _name = lambda k: _literal(sep.join(k)) |
|
1188 | _name = lambda k: _literal(sep.join(k)) | |
1186 |
|
1189 |
@@ -115,7 +115,8 b' def UsersGroupForm(edit=False, old_data=' | |||||
115 | return _UsersGroupForm |
|
115 | return _UsersGroupForm | |
116 |
|
116 | |||
117 |
|
117 | |||
118 |
def ReposGroupForm(edit=False, old_data={}, available_groups=[] |
|
118 | def ReposGroupForm(edit=False, old_data={}, available_groups=[], | |
|
119 | can_create_in_root=False): | |||
119 | class _ReposGroupForm(formencode.Schema): |
|
120 | class _ReposGroupForm(formencode.Schema): | |
120 | allow_extra_fields = True |
|
121 | allow_extra_fields = True | |
121 | filter_extra_fields = False |
|
122 | filter_extra_fields = False | |
@@ -123,10 +124,15 b' def ReposGroupForm(edit=False, old_data=' | |||||
123 | group_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), |
|
124 | group_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), | |
124 | v.SlugifyName()) |
|
125 | v.SlugifyName()) | |
125 | group_description = v.UnicodeString(strip=True, min=1, |
|
126 | group_description = v.UnicodeString(strip=True, min=1, | |
126 |
not_empty= |
|
127 | not_empty=False) | |
127 | group_parent_id = v.OneOf(available_groups, hideList=False, |
|
128 | if edit: | |
128 | testValueList=True, |
|
129 | #FIXME: do a special check that we cannot move a group to one of | |
129 | if_missing=None, not_empty=False) |
|
130 | #it's children | |
|
131 | pass | |||
|
132 | group_parent_id = All(v.CanCreateGroup(can_create_in_root), | |||
|
133 | v.OneOf(available_groups, hideList=False, | |||
|
134 | testValueList=True, | |||
|
135 | if_missing=None, not_empty=True)) | |||
130 | enable_locking = v.StringBoolean(if_missing=False) |
|
136 | enable_locking = v.StringBoolean(if_missing=False) | |
131 | recursive = v.StringBoolean(if_missing=False) |
|
137 | recursive = v.StringBoolean(if_missing=False) | |
132 | chained_validators = [v.ValidReposGroup(edit, old_data), |
|
138 | chained_validators = [v.ValidReposGroup(edit, old_data), |
@@ -140,16 +140,21 b' class ReposGroupModel(BaseModel):' | |||||
140 | group.name) |
|
140 | group.name) | |
141 | shutil.move(rm_path, os.path.join(self.repos_path, _d)) |
|
141 | shutil.move(rm_path, os.path.join(self.repos_path, _d)) | |
142 |
|
142 | |||
143 | def create(self, group_name, group_description, parent=None, just_db=False): |
|
143 | def create(self, group_name, group_description, owner, parent=None, just_db=False): | |
144 | try: |
|
144 | try: | |
145 | new_repos_group = RepoGroup() |
|
145 | new_repos_group = RepoGroup() | |
146 | new_repos_group.group_description = group_description |
|
146 | new_repos_group.group_description = group_description or group_name | |
147 | new_repos_group.parent_group = self._get_repos_group(parent) |
|
147 | new_repos_group.parent_group = self._get_repos_group(parent) | |
148 | new_repos_group.group_name = new_repos_group.get_new_name(group_name) |
|
148 | new_repos_group.group_name = new_repos_group.get_new_name(group_name) | |
149 |
|
149 | |||
150 | self.sa.add(new_repos_group) |
|
150 | self.sa.add(new_repos_group) | |
151 | self._create_default_perms(new_repos_group) |
|
151 | self._create_default_perms(new_repos_group) | |
152 |
|
152 | |||
|
153 | #create an ADMIN permission for owner, later owner should go into | |||
|
154 | #the owner field of groups | |||
|
155 | self.grant_user_permission(repos_group=new_repos_group, | |||
|
156 | user=owner, perm='group.admin') | |||
|
157 | ||||
153 | if not just_db: |
|
158 | if not just_db: | |
154 | # 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 | |
155 | # throw any exceptions, create filesystem dirs at the very end |
|
160 | # throw any exceptions, create filesystem dirs at the very end | |
@@ -229,10 +234,10 b' class ReposGroupModel(BaseModel):' | |||||
229 | break |
|
234 | break | |
230 | return updates |
|
235 | return updates | |
231 |
|
236 | |||
232 |
def update(self, repos_group |
|
237 | def update(self, repos_group, form_data): | |
233 |
|
238 | |||
234 | try: |
|
239 | try: | |
235 |
repos_group = |
|
240 | repos_group = self._get_repos_group(repos_group) | |
236 | recursive = form_data['recursive'] |
|
241 | recursive = form_data['recursive'] | |
237 | # iterate over all members(if in recursive mode) of this groups and |
|
242 | # iterate over all members(if in recursive mode) of this groups and | |
238 | # set the permissions ! |
|
243 | # set the permissions ! |
@@ -77,11 +77,15 b' class CachedRepoList(object):' | |||||
77 | super fast |
|
77 | super fast | |
78 | """ |
|
78 | """ | |
79 |
|
79 | |||
80 | def __init__(self, db_repo_list, repos_path, order_by=None): |
|
80 | def __init__(self, db_repo_list, repos_path, order_by=None, perm_set=None): | |
81 | self.db_repo_list = db_repo_list |
|
81 | self.db_repo_list = db_repo_list | |
82 | self.repos_path = repos_path |
|
82 | self.repos_path = repos_path | |
83 | self.order_by = order_by |
|
83 | self.order_by = order_by | |
84 | self.reversed = (order_by or '').startswith('-') |
|
84 | self.reversed = (order_by or '').startswith('-') | |
|
85 | if not perm_set: | |||
|
86 | perm_set = ['repository.read', 'repository.write', | |||
|
87 | 'repository.admin'] | |||
|
88 | self.perm_set = perm_set | |||
85 |
|
89 | |||
86 | def __len__(self): |
|
90 | def __len__(self): | |
87 | return len(self.db_repo_list) |
|
91 | return len(self.db_repo_list) | |
@@ -98,7 +102,7 b' class CachedRepoList(object):' | |||||
98 | scmr = dbr.scm_instance_cached(cache_map) |
|
102 | scmr = dbr.scm_instance_cached(cache_map) | |
99 | # check permission at this level |
|
103 | # check permission at this level | |
100 | if not HasRepoPermissionAny( |
|
104 | if not HasRepoPermissionAny( | |
101 | 'repository.read', 'repository.write', 'repository.admin' |
|
105 | *self.perm_set | |
102 | )(dbr.repo_name, 'get repo check'): |
|
106 | )(dbr.repo_name, 'get repo check'): | |
103 | continue |
|
107 | continue | |
104 |
|
108 | |||
@@ -143,7 +147,7 b' class SimpleCachedRepoList(CachedRepoLis' | |||||
143 | for dbr in self.db_repo_list: |
|
147 | for dbr in self.db_repo_list: | |
144 | # check permission at this level |
|
148 | # check permission at this level | |
145 | if not HasRepoPermissionAny( |
|
149 | if not HasRepoPermissionAny( | |
146 | 'repository.read', 'repository.write', 'repository.admin' |
|
150 | *self.perm_set | |
147 | )(dbr.repo_name, 'get repo check'): |
|
151 | )(dbr.repo_name, 'get repo check'): | |
148 | continue |
|
152 | continue | |
149 |
|
153 | |||
@@ -160,8 +164,18 b' class SimpleCachedRepoList(CachedRepoLis' | |||||
160 |
|
164 | |||
161 | class GroupList(object): |
|
165 | class GroupList(object): | |
162 |
|
166 | |||
163 | def __init__(self, db_repo_group_list): |
|
167 | def __init__(self, db_repo_group_list, perm_set=None): | |
|
168 | """ | |||
|
169 | Creates iterator from given list of group objects, additionally | |||
|
170 | checking permission for them from perm_set var | |||
|
171 | ||||
|
172 | :param db_repo_group_list: | |||
|
173 | :param perm_set: list of permissons to check | |||
|
174 | """ | |||
164 | self.db_repo_group_list = db_repo_group_list |
|
175 | self.db_repo_group_list = db_repo_group_list | |
|
176 | if not perm_set: | |||
|
177 | perm_set = ['group.read', 'group.write', 'group.admin'] | |||
|
178 | self.perm_set = perm_set | |||
165 |
|
179 | |||
166 | def __len__(self): |
|
180 | def __len__(self): | |
167 | return len(self.db_repo_group_list) |
|
181 | return len(self.db_repo_group_list) | |
@@ -173,7 +187,7 b' class GroupList(object):' | |||||
173 | for dbgr in self.db_repo_group_list: |
|
187 | for dbgr in self.db_repo_group_list: | |
174 | # check permission at this level |
|
188 | # check permission at this level | |
175 | if not HasReposGroupPermissionAny( |
|
189 | if not HasReposGroupPermissionAny( | |
176 | 'group.read', 'group.write', 'group.admin' |
|
190 | *self.perm_set | |
177 | )(dbgr.group_name, 'get group repo check'): |
|
191 | )(dbgr.group_name, 'get group repo check'): | |
178 | continue |
|
192 | continue | |
179 |
|
193 |
@@ -475,11 +475,19 b' def CanWriteGroup():' | |||||
475 | "to create repository in this group") |
|
475 | "to create repository in this group") | |
476 | } |
|
476 | } | |
477 |
|
477 | |||
|
478 | def to_python(self, value, state): | |||
|
479 | #root location | |||
|
480 | if value in [-1, "-1"]: | |||
|
481 | return None | |||
|
482 | return value | |||
|
483 | ||||
478 | def validate_python(self, value, state): |
|
484 | def validate_python(self, value, state): | |
479 | gr = RepoGroup.get(value) |
|
485 | gr = RepoGroup.get(value) | |
480 | if not HasReposGroupPermissionAny( |
|
486 | gr_name = gr.group_name if gr else None # None means ROOT location | |
481 |
|
|
487 | val = HasReposGroupPermissionAny('group.write', 'group.admin') | |
482 | )(gr.group_name, 'get group of repo form'): |
|
488 | forbidden = not val(gr_name, 'can write into group validator') | |
|
489 | #parent group need to be existing | |||
|
490 | if gr and forbidden: | |||
483 | msg = M(self, 'permission_denied', state) |
|
491 | msg = M(self, 'permission_denied', state) | |
484 | raise formencode.Invalid(msg, value, state, |
|
492 | raise formencode.Invalid(msg, value, state, | |
485 | error_dict=dict(repo_type=msg) |
|
493 | error_dict=dict(repo_type=msg) | |
@@ -487,6 +495,46 b' def CanWriteGroup():' | |||||
487 | return _validator |
|
495 | return _validator | |
488 |
|
496 | |||
489 |
|
497 | |||
|
498 | def CanCreateGroup(can_create_in_root=False): | |||
|
499 | class _validator(formencode.validators.FancyValidator): | |||
|
500 | messages = { | |||
|
501 | 'permission_denied': _(u"You don't have permissions " | |||
|
502 | "to create a group in this location") | |||
|
503 | } | |||
|
504 | ||||
|
505 | def to_python(self, value, state): | |||
|
506 | #root location | |||
|
507 | if value in [-1, "-1"]: | |||
|
508 | return None | |||
|
509 | return value | |||
|
510 | ||||
|
511 | def validate_python(self, value, state): | |||
|
512 | #TODO: REMOVE THIS !! | |||
|
513 | ################################ | |||
|
514 | import ipdb;ipdb.set_trace() | |||
|
515 | print 'setting ipdb debuggin for rhodecode.model.validators._validator.validate_python' | |||
|
516 | ################################ | |||
|
517 | ||||
|
518 | ||||
|
519 | gr = RepoGroup.get(value) | |||
|
520 | gr_name = gr.group_name if gr else None # None means ROOT location | |||
|
521 | ||||
|
522 | if can_create_in_root and gr is None: | |||
|
523 | #we can create in root, we're fine no validations required | |||
|
524 | return | |||
|
525 | ||||
|
526 | forbidden_in_root = gr is None and can_create_in_root is False | |||
|
527 | val = HasReposGroupPermissionAny('group.admin') | |||
|
528 | forbidden = not val(gr_name, 'can create group validator') | |||
|
529 | if forbidden_in_root or forbidden: | |||
|
530 | msg = M(self, 'permission_denied', state) | |||
|
531 | raise formencode.Invalid(msg, value, state, | |||
|
532 | error_dict=dict(group_parent_id=msg) | |||
|
533 | ) | |||
|
534 | ||||
|
535 | return _validator | |||
|
536 | ||||
|
537 | ||||
490 | def ValidPerms(type_='repo'): |
|
538 | def ValidPerms(type_='repo'): | |
491 | if type_ == 'group': |
|
539 | if type_ == 'group': | |
492 | EMPTY_PERM = 'group.none' |
|
540 | EMPTY_PERM = 'group.none' |
@@ -4631,7 +4631,7 b' PULL REQUESTS' | |||||
4631 | } |
|
4631 | } | |
4632 |
|
4632 | |||
4633 | #perms .perm_tag.write{ |
|
4633 | #perms .perm_tag.write{ | |
4634 |
background-color: # |
|
4634 | background-color: #DB7525; | |
4635 | color: #ffffff; |
|
4635 | color: #ffffff; | |
4636 | } |
|
4636 | } | |
4637 |
|
4637 |
@@ -148,7 +148,7 b'' | |||||
148 | %if section == 'repositories': |
|
148 | %if section == 'repositories': | |
149 | <a href="${h.url('edit_repo',repo_name=k,anchor='permissions_manage')}">${_('edit')}</a> |
|
149 | <a href="${h.url('edit_repo',repo_name=k,anchor='permissions_manage')}">${_('edit')}</a> | |
150 | %elif section == 'repositories_groups': |
|
150 | %elif section == 'repositories_groups': | |
151 |
<a href="${h.url('edit_repos_group', |
|
151 | <a href="${h.url('edit_repos_group',group_name=k,anchor='permissions_manage')}">${_('edit')}</a> | |
152 | %else: |
|
152 | %else: | |
153 | -- |
|
153 | -- | |
154 | %endif |
|
154 | %endif |
@@ -28,7 +28,7 b'' | |||||
28 | </ul> |
|
28 | </ul> | |
29 | </div> |
|
29 | </div> | |
30 | <!-- end box / title --> |
|
30 | <!-- end box / title --> | |
31 |
${h.form(url('repos_group', |
|
31 | ${h.form(url('repos_group',group_name=c.repos_group.group_name),method='put')} | |
32 | <div class="form"> |
|
32 | <div class="form"> | |
33 | <!-- fields --> |
|
33 | <!-- fields --> | |
34 | <div class="fields"> |
|
34 | <div class="fields"> |
@@ -51,12 +51,12 b'' | |||||
51 | <td>${gr.group_description}</td> |
|
51 | <td>${gr.group_description}</td> | |
52 | <td><b>${gr_cn}</b></td> |
|
52 | <td><b>${gr_cn}</b></td> | |
53 | <td> |
|
53 | <td> | |
54 |
<a href="${h.url('edit_repos_group', |
|
54 | <a href="${h.url('edit_repos_group',group_name=gr.group_name)}" title="${_('edit')}"> | |
55 | ${h.submit('edit_%s' % gr.group_name,_('edit'),class_="edit_icon action_button")} |
|
55 | ${h.submit('edit_%s' % gr.group_name,_('edit'),class_="edit_icon action_button")} | |
56 | </a> |
|
56 | </a> | |
57 | </td> |
|
57 | </td> | |
58 | <td> |
|
58 | <td> | |
59 |
${h.form(url('repos_group', |
|
59 | ${h.form(url('repos_group', group_name=gr.group_name),method='delete')} | |
60 | ${h.submit('remove_%s' % gr.name,_('delete'),class_="delete_icon action_button",onclick="return confirm('"+ungettext('Confirm to delete this group: %s with %s repository','Confirm to delete this group: %s with %s repositories',gr_cn) % (gr.name,gr_cn)+"');")} |
|
60 | ${h.submit('remove_%s' % gr.name,_('delete'),class_="delete_icon action_button",onclick="return confirm('"+ungettext('Confirm to delete this group: %s with %s repository','Confirm to delete this group: %s with %s repositories',gr_cn) % (gr.name,gr_cn)+"');")} | |
61 | ${h.end_form()} |
|
61 | ${h.end_form()} | |
62 | </td> |
|
62 | </td> |
@@ -231,7 +231,7 b'' | |||||
231 | %if section == 'repositories': |
|
231 | %if section == 'repositories': | |
232 | <a href="${h.url('edit_repo',repo_name=k,anchor='permissions_manage')}">${_('edit')}</a> |
|
232 | <a href="${h.url('edit_repo',repo_name=k,anchor='permissions_manage')}">${_('edit')}</a> | |
233 | %elif section == 'repositories_groups': |
|
233 | %elif section == 'repositories_groups': | |
234 |
<a href="${h.url('edit_repos_group', |
|
234 | <a href="${h.url('edit_repos_group',group_name=k,anchor='permissions_manage')}">${_('edit')}</a> | |
235 | %else: |
|
235 | %else: | |
236 | -- |
|
236 | -- | |
237 | %endif |
|
237 | %endif |
@@ -206,7 +206,7 b'' | |||||
206 | %if section == 'repositories': |
|
206 | %if section == 'repositories': | |
207 | <a href="${h.url('edit_repo',repo_name=k,anchor='permissions_manage')}">${_('edit')}</a> |
|
207 | <a href="${h.url('edit_repo',repo_name=k,anchor='permissions_manage')}">${_('edit')}</a> | |
208 | %elif section == 'repositories_groups': |
|
208 | %elif section == 'repositories_groups': | |
209 |
<a href="${h.url('edit_repos_group', |
|
209 | <a href="${h.url('edit_repos_group',group_name=k,anchor='permissions_manage')}">${_('edit')}</a> | |
210 | %else: |
|
210 | %else: | |
211 | -- |
|
211 | -- | |
212 | %endif |
|
212 | %endif |
@@ -6,17 +6,22 b'' | |||||
6 | <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/> ${parent.breadcrumbs()} <span id="repo_count">0</span> ${_('repositories')} |
|
6 | <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/> ${parent.breadcrumbs()} <span id="repo_count">0</span> ${_('repositories')} | |
7 | </h5> |
|
7 | </h5> | |
8 | %if c.rhodecode_user.username != 'default': |
|
8 | %if c.rhodecode_user.username != 'default': | |
|
9 | <ul class="links"> | |||
9 | %if h.HasPermissionAny('hg.admin','hg.create.repository')(): |
|
10 | %if h.HasPermissionAny('hg.admin','hg.create.repository')(): | |
10 | <ul class="links"> |
|
|||
11 | <li> |
|
11 | <li> | |
12 | %if c.group: |
|
12 | %if c.group: | |
13 | <span>${h.link_to(_('Add repository'),h.url('admin_settings_create_repository',parent_group=c.group.group_id))}</span> |
|
13 | <span>${h.link_to(_('Add repository'),h.url('admin_settings_create_repository',parent_group=c.group.group_id))}</span> | |
14 | %else: |
|
14 | %else: | |
15 | <span>${h.link_to(_('Add repository'),h.url('admin_settings_create_repository'))}</span> |
|
15 | <span>${h.link_to(_('Add repository'),h.url('admin_settings_create_repository'))}</span> | |
16 | %endif |
|
16 | %endif | |
17 | </li> |
|
17 | </li> | |
18 | </ul> |
|
|||
19 | %endif |
|
18 | %endif | |
|
19 | %if c.group and h.HasReposGroupPermissionAny('group.admin')(c.group.group_name): | |||
|
20 | <li> | |||
|
21 | <span>${h.link_to(_('Edit group'),h.url('edit_repos_group',group_name=c.group.group_name), title=_('You have admin right to this group, and can edit it'))}</span> | |||
|
22 | </li> | |||
|
23 | %endif | |||
|
24 | </ul> | |||
20 | %endif |
|
25 | %endif | |
21 | </div> |
|
26 | </div> | |
22 | <!-- end box / title --> |
|
27 | <!-- end box / title --> |
@@ -90,7 +90,8 b' class TestAdminReposController(TestContr' | |||||
90 | ## create GROUP |
|
90 | ## create GROUP | |
91 | group_name = 'sometest' |
|
91 | group_name = 'sometest' | |
92 | gr = ReposGroupModel().create(group_name=group_name, |
|
92 | gr = ReposGroupModel().create(group_name=group_name, | |
93 |
group_description='test', |
|
93 | group_description='test', | |
|
94 | owner=TEST_USER_ADMIN_LOGIN) | |||
94 | self.Session().commit() |
|
95 | self.Session().commit() | |
95 |
|
96 | |||
96 | repo_name = 'ingroup' |
|
97 | repo_name = 'ingroup' |
@@ -1,43 +1,51 b'' | |||||
1 | from rhodecode.tests import * |
|
1 | from rhodecode.tests import * | |
2 |
|
2 | |||
|
3 | ||||
3 | class TestReposGroupsController(TestController): |
|
4 | class TestReposGroupsController(TestController): | |
4 |
|
5 | |||
5 | def test_index(self): |
|
6 | def test_index(self): | |
|
7 | self.log_user() | |||
6 | response = self.app.get(url('repos_groups')) |
|
8 | response = self.app.get(url('repos_groups')) | |
7 | # Test response... |
|
9 | response.mustcontain('There are no repositories groups yet') | |
8 |
|
10 | |||
9 | def test_index_as_xml(self): |
|
11 | # def test_index_as_xml(self): | |
10 | response = self.app.get(url('formatted_repos_groups', format='xml')) |
|
12 | # response = self.app.get(url('formatted_repos_groups', format='xml')) | |
11 |
|
13 | # | ||
12 | def test_create(self): |
|
14 | # def test_create(self): | |
13 | response = self.app.post(url('repos_groups')) |
|
15 | # response = self.app.post(url('repos_groups')) | |
14 |
|
16 | |||
15 | def test_new(self): |
|
17 | def test_new(self): | |
|
18 | self.log_user() | |||
16 | response = self.app.get(url('new_repos_group')) |
|
19 | response = self.app.get(url('new_repos_group')) | |
17 |
|
20 | |||
18 |
def test_new_ |
|
21 | def test_new_by_regular_user(self): | |
19 | response = self.app.get(url('formatted_new_repos_group', format='xml')) |
|
22 | self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) | |
20 |
|
23 | response = self.app.get(url('new_repos_group'), status=403) | ||
21 | def test_update(self): |
|
24 | # | |
22 | response = self.app.put(url('repos_group', id=1)) |
|
25 | # def test_new_as_xml(self): | |
23 |
|
26 | # response = self.app.get(url('formatted_new_repos_group', format='xml')) | ||
24 | def test_update_browser_fakeout(self): |
|
27 | # | |
25 | response = self.app.post(url('repos_group', id=1), params=dict(_method='put')) |
|
28 | # def test_update(self): | |
26 |
|
29 | # response = self.app.put(url('repos_group', group_name=1)) | ||
27 | def test_delete(self): |
|
30 | # | |
28 | response = self.app.delete(url('repos_group', id=1)) |
|
31 | # def test_update_browser_fakeout(self): | |
29 |
|
32 | # response = self.app.post(url('repos_group', group_name=1), params=dict(_method='put')) | ||
30 | def test_delete_browser_fakeout(self): |
|
33 | # | |
31 | response = self.app.post(url('repos_group', id=1), params=dict(_method='delete')) |
|
34 | # def test_delete(self): | |
32 |
|
35 | # self.log_user() | ||
33 | def test_show(self): |
|
36 | # response = self.app.delete(url('repos_group', group_name=1)) | |
34 | response = self.app.get(url('repos_group', id=1)) |
|
37 | # | |
35 |
|
38 | # def test_delete_browser_fakeout(self): | ||
36 | def test_show_as_xml(self): |
|
39 | # response = self.app.post(url('repos_group', group_name=1), params=dict(_method='delete')) | |
37 | response = self.app.get(url('formatted_repos_group', id=1, format='xml')) |
|
40 | # | |
38 |
|
41 | # def test_show(self): | ||
39 | def test_edit(self): |
|
42 | # response = self.app.get(url('repos_group', group_name=1)) | |
40 | response = self.app.get(url('edit_repos_group', id=1)) |
|
43 | # | |
41 |
|
44 | # def test_show_as_xml(self): | ||
42 | def test_edit_as_xml(self): |
|
45 | # response = self.app.get(url('formatted_repos_group', group_name=1, format='xml')) | |
43 | response = self.app.get(url('formatted_edit_repos_group', id=1, format='xml')) |
|
46 | # | |
|
47 | # def test_edit(self): | |||
|
48 | # response = self.app.get(url('edit_repos_group', group_name=1)) | |||
|
49 | # | |||
|
50 | # def test_edit_as_xml(self): | |||
|
51 | # response = self.app.get(url('formatted_edit_repos_group', group_name=1, format='xml')) |
@@ -21,7 +21,7 b" def _make_group(path, desc='desc', paren" | |||||
21 | return gr |
|
21 | return gr | |
22 | if isinstance(parent_id, RepoGroup): |
|
22 | if isinstance(parent_id, RepoGroup): | |
23 | parent_id = parent_id.group_id |
|
23 | parent_id = parent_id.group_id | |
24 | gr = ReposGroupModel().create(path, desc, parent_id) |
|
24 | gr = ReposGroupModel().create(path, desc, TEST_USER_ADMIN_LOGIN, parent_id) | |
25 | return gr |
|
25 | return gr | |
26 |
|
26 | |||
27 |
|
27 |
@@ -17,7 +17,7 b" def _make_group(path, desc='desc', paren" | |||||
17 | return gr |
|
17 | return gr | |
18 | if isinstance(parent_id, RepoGroup): |
|
18 | if isinstance(parent_id, RepoGroup): | |
19 | parent_id = parent_id.group_id |
|
19 | parent_id = parent_id.group_id | |
20 | gr = ReposGroupModel().create(path, desc, parent_id) |
|
20 | gr = ReposGroupModel().create(path, desc, TEST_USER_ADMIN_LOGIN, parent_id) | |
21 | return gr |
|
21 | return gr | |
22 |
|
22 | |||
23 |
|
23 |
@@ -79,7 +79,8 b' class TestReposGroups(unittest.TestCase)' | |||||
79 | {'group_name': HG_REPO, }) |
|
79 | {'group_name': HG_REPO, }) | |
80 | gr = model.create(group_name='test_gr', group_description='desc', |
|
80 | gr = model.create(group_name='test_gr', group_description='desc', | |
81 | parent=None, |
|
81 | parent=None, | |
82 |
just_db=True |
|
82 | just_db=True, | |
|
83 | owner=TEST_USER_ADMIN_LOGIN) | |||
83 | self.assertRaises(formencode.Invalid, |
|
84 | self.assertRaises(formencode.Invalid, | |
84 | validator.to_python, {'group_name': gr.group_name, }) |
|
85 | validator.to_python, {'group_name': gr.group_name, }) | |
85 |
|
86 | |||
@@ -150,7 +151,8 b' class TestReposGroups(unittest.TestCase)' | |||||
150 |
|
151 | |||
151 | gr = ReposGroupModel().create(group_name='group_test', |
|
152 | gr = ReposGroupModel().create(group_name='group_test', | |
152 | group_description='desc', |
|
153 | group_description='desc', | |
153 |
parent=None, |
|
154 | parent=None, | |
|
155 | owner=TEST_USER_ADMIN_LOGIN) | |||
154 | self.assertRaises(formencode.Invalid, |
|
156 | self.assertRaises(formencode.Invalid, | |
155 | validator.to_python, {'repo_name': gr.group_name}) |
|
157 | validator.to_python, {'repo_name': gr.group_name}) | |
156 |
|
158 |
General Comments 0
You need to be logged in to leave comments.
Login now