Show More
@@ -97,6 +97,7 b' class ReposController(BaseController):' | |||
|
97 | 97 | |
|
98 | 98 | return redirect(url('repos')) |
|
99 | 99 | |
|
100 | ##override defaults for exact repo info here git/hg etc | |
|
100 | 101 | choices, c.landing_revs = ScmModel().get_repo_landing_revs(c.repo_info) |
|
101 | 102 | c.landing_revs_choices = choices |
|
102 | 103 | |
@@ -239,7 +240,15 b' class ReposController(BaseController):' | |||
|
239 | 240 | new_repo = request.GET.get('repo', '') |
|
240 | 241 | c.new_repo = repo_name_slug(new_repo) |
|
241 | 242 | self.__load_defaults() |
|
242 | return render('admin/repos/repo_add.html') | |
|
243 | ## apply the defaults from defaults page | |
|
244 | defaults = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True) | |
|
245 | return htmlfill.render( | |
|
246 | render('admin/repos/repo_add.html'), | |
|
247 | defaults=defaults, | |
|
248 | errors={}, | |
|
249 | prefix_error=False, | |
|
250 | encoding="UTF-8" | |
|
251 | ) | |
|
243 | 252 | |
|
244 | 253 | @HasPermissionAllDecorator('hg.admin') |
|
245 | 254 | def update(self, repo_name): |
@@ -263,7 +272,7 b' class ReposController(BaseController):' | |||
|
263 | 272 | landing_revs=c.landing_revs_choices)() |
|
264 | 273 | try: |
|
265 | 274 | form_result = _form.to_python(dict(request.POST)) |
|
266 | repo = repo_model.update(repo_name, form_result) | |
|
275 | repo = repo_model.update(repo_name, **form_result) | |
|
267 | 276 | invalidate_cache('get_repo_cached_%s' % repo_name) |
|
268 | 277 | h.flash(_('Repository %s updated successfully') % repo_name, |
|
269 | 278 | category='success') |
@@ -65,23 +65,38 b' class SettingsController(BaseRepoControl' | |||
|
65 | 65 | choices, c.landing_revs = ScmModel().get_repo_landing_revs() |
|
66 | 66 | c.landing_revs_choices = choices |
|
67 | 67 | |
|
68 | @HasRepoPermissionAllDecorator('repository.admin') | |
|
69 | def index(self, repo_name): | |
|
70 | repo_model = RepoModel() | |
|
71 | c.repo_info = repo = repo_model.get_by_repo_name(repo_name) | |
|
72 |
|
|
|
68 | def __load_data(self, repo_name=None): | |
|
69 | """ | |
|
70 | Load defaults settings for edit, and update | |
|
71 | ||
|
72 | :param repo_name: | |
|
73 | """ | |
|
74 | self.__load_defaults() | |
|
75 | ||
|
76 | c.repo_info = db_repo = Repository.get_by_repo_name(repo_name) | |
|
77 | repo = db_repo.scm_instance | |
|
78 | ||
|
79 | if c.repo_info is None: | |
|
73 | 80 | h.flash(_('%s repository is not mapped to db perhaps' |
|
74 |
' it was created or renamed from the file |
|
|
81 | ' it was created or renamed from the filesystem' | |
|
75 | 82 | ' please run the application again' |
|
76 | 83 | ' in order to rescan repositories') % repo_name, |
|
77 | 84 | category='error') |
|
78 | 85 | |
|
79 | 86 | return redirect(url('home')) |
|
80 | 87 | |
|
81 | self.__load_defaults() | |
|
88 | ##override defaults for exact repo info here git/hg etc | |
|
89 | choices, c.landing_revs = ScmModel().get_repo_landing_revs(c.repo_info) | |
|
90 | c.landing_revs_choices = choices | |
|
82 | 91 | |
|
83 | 92 | defaults = RepoModel()._get_defaults(repo_name) |
|
84 | 93 | |
|
94 | return defaults | |
|
95 | ||
|
96 | @HasRepoPermissionAllDecorator('repository.admin') | |
|
97 | def index(self, repo_name): | |
|
98 | defaults = self.__load_data(repo_name) | |
|
99 | ||
|
85 | 100 | return htmlfill.render( |
|
86 | 101 | render('settings/repo_settings.html'), |
|
87 | 102 | defaults=defaults, |
@@ -91,10 +106,12 b' class SettingsController(BaseRepoControl' | |||
|
91 | 106 | |
|
92 | 107 | @HasRepoPermissionAllDecorator('repository.admin') |
|
93 | 108 | def update(self, repo_name): |
|
109 | self.__load_defaults() | |
|
94 | 110 | repo_model = RepoModel() |
|
95 | 111 | changed_name = repo_name |
|
96 | ||
|
97 | self.__load_defaults() | |
|
112 | #override the choices with extracted revisions ! | |
|
113 | choices, c.landing_revs = ScmModel().get_repo_landing_revs(repo_name) | |
|
114 | c.landing_revs_choices = choices | |
|
98 | 115 | |
|
99 | 116 | _form = RepoSettingsForm(edit=True, |
|
100 | 117 | old_data={'repo_name': repo_name}, |
@@ -102,8 +119,7 b' class SettingsController(BaseRepoControl' | |||
|
102 | 119 | landing_revs=c.landing_revs_choices)() |
|
103 | 120 | try: |
|
104 | 121 | form_result = _form.to_python(dict(request.POST)) |
|
105 | ||
|
106 | repo_model.update(repo_name, form_result) | |
|
122 | repo_model.update(repo_name, **form_result) | |
|
107 | 123 | invalidate_cache('get_repo_cached_%s' % repo_name) |
|
108 | 124 | h.flash(_('Repository %s updated successfully') % repo_name, |
|
109 | 125 | category='success') |
@@ -112,15 +128,15 b' class SettingsController(BaseRepoControl' | |||
|
112 | 128 | changed_name, self.ip_addr, self.sa) |
|
113 | 129 | Session().commit() |
|
114 | 130 | except formencode.Invalid, errors: |
|
115 | c.repo_info = repo_model.get_by_repo_name(repo_name) | |
|
116 | c.users_array = repo_model.get_users_js() | |
|
117 | errors.value.update({'user': c.repo_info.user.username}) | |
|
131 | defaults = self.__load_data(repo_name) | |
|
132 | defaults.update(errors.value) | |
|
118 | 133 | return htmlfill.render( |
|
119 | 134 | render('settings/repo_settings.html'), |
|
120 | 135 | defaults=errors.value, |
|
121 | 136 | errors=errors.error_dict or {}, |
|
122 | 137 | prefix_error=False, |
|
123 | 138 | encoding="UTF-8") |
|
139 | ||
|
124 | 140 | except Exception: |
|
125 | 141 | log.error(traceback.format_exc()) |
|
126 | 142 | h.flash(_('error occurred during update of repository %s') \ |
@@ -173,7 +173,7 b' def RepoForm(edit=False, old_data={}, su' | |||
|
173 | 173 | repo_groups=[], landing_revs=[]): |
|
174 | 174 | class _RepoForm(formencode.Schema): |
|
175 | 175 | allow_extra_fields = True |
|
176 |
filter_extra_fields = |
|
|
176 | filter_extra_fields = False | |
|
177 | 177 | repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), |
|
178 | 178 | v.SlugifyName()) |
|
179 | 179 | repo_group = All(v.CanWriteGroup(), |
@@ -181,11 +181,12 b' def RepoForm(edit=False, old_data={}, su' | |||
|
181 | 181 | repo_type = v.OneOf(supported_backends) |
|
182 | 182 | repo_description = v.UnicodeString(strip=True, min=1, not_empty=False) |
|
183 | 183 | repo_private = v.StringBoolean(if_missing=False) |
|
184 | repo_landing_rev = v.OneOf(landing_revs, hideList=True) | |
|
185 | clone_uri = All(v.UnicodeString(strip=True, min=1, not_empty=False)) | |
|
186 | ||
|
184 | 187 | repo_enable_statistics = v.StringBoolean(if_missing=False) |
|
185 | 188 | repo_enable_downloads = v.StringBoolean(if_missing=False) |
|
186 | 189 | repo_enable_locking = v.StringBoolean(if_missing=False) |
|
187 | repo_landing_rev = v.OneOf(landing_revs, hideList=True) | |
|
188 | clone_uri = All(v.UnicodeString(strip=True, min=1, not_empty=False)) | |
|
189 | 190 | |
|
190 | 191 | if edit: |
|
191 | 192 | #this is repo owner |
@@ -197,6 +198,27 b' def RepoForm(edit=False, old_data={}, su' | |||
|
197 | 198 | return _RepoForm |
|
198 | 199 | |
|
199 | 200 | |
|
201 | def RepoSettingsForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(), | |
|
202 | repo_groups=[], landing_revs=[]): | |
|
203 | class _RepoForm(formencode.Schema): | |
|
204 | allow_extra_fields = True | |
|
205 | filter_extra_fields = False | |
|
206 | repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), | |
|
207 | v.SlugifyName()) | |
|
208 | repo_group = All(v.CanWriteGroup(), | |
|
209 | v.OneOf(repo_groups, hideList=True)) | |
|
210 | repo_description = v.UnicodeString(strip=True, min=1, not_empty=False) | |
|
211 | repo_private = v.StringBoolean(if_missing=False) | |
|
212 | repo_landing_rev = v.OneOf(landing_revs, hideList=True) | |
|
213 | clone_uri = All(v.UnicodeString(strip=True, min=1, not_empty=False)) | |
|
214 | ||
|
215 | chained_validators = [v.ValidCloneUri(), | |
|
216 | v.ValidRepoName(edit, old_data), | |
|
217 | v.ValidPerms(), | |
|
218 | v.ValidSettings()] | |
|
219 | return _RepoForm | |
|
220 | ||
|
221 | ||
|
200 | 222 | def RepoForkForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(), |
|
201 | 223 | repo_groups=[], landing_revs=[]): |
|
202 | 224 | class _RepoForkForm(formencode.Schema): |
@@ -218,23 +240,6 b' def RepoForkForm(edit=False, old_data={}' | |||
|
218 | 240 | return _RepoForkForm |
|
219 | 241 | |
|
220 | 242 | |
|
221 | def RepoSettingsForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(), | |
|
222 | repo_groups=[], landing_revs=[]): | |
|
223 | class _RepoForm(formencode.Schema): | |
|
224 | allow_extra_fields = True | |
|
225 | filter_extra_fields = False | |
|
226 | repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), | |
|
227 | v.SlugifyName()) | |
|
228 | description = v.UnicodeString(strip=True, min=1, not_empty=True) | |
|
229 | repo_group = All(v.CanWriteGroup(), | |
|
230 | v.OneOf(repo_groups, hideList=True)) | |
|
231 | private = v.StringBoolean(if_missing=False) | |
|
232 | landing_rev = v.OneOf(landing_revs, hideList=True) | |
|
233 | chained_validators = [v.ValidRepoName(edit, old_data), v.ValidPerms(), | |
|
234 | v.ValidSettings()] | |
|
235 | return _RepoForm | |
|
236 | ||
|
237 | ||
|
238 | 243 | def ApplicationSettingsForm(): |
|
239 | 244 | class _ApplicationSettingsForm(formencode.Schema): |
|
240 | 245 | allow_extra_fields = True |
@@ -31,7 +31,8 b' from datetime import datetime' | |||
|
31 | 31 | |
|
32 | 32 | from rhodecode.lib.vcs.backends import get_backend |
|
33 | 33 | from rhodecode.lib.compat import json |
|
34 | from rhodecode.lib.utils2 import LazyProperty, safe_str, safe_unicode | |
|
34 | from rhodecode.lib.utils2 import LazyProperty, safe_str, safe_unicode,\ | |
|
35 | remove_prefix | |
|
35 | 36 | from rhodecode.lib.caching_query import FromCache |
|
36 | 37 | from rhodecode.lib.hooks import log_create_repository, log_delete_repository |
|
37 | 38 | |
@@ -131,6 +132,16 b' class RepoModel(BaseModel):' | |||
|
131 | 132 | defaults['repo_group'] = getattr(group[-1] if group else None, |
|
132 | 133 | 'group_id', None) |
|
133 | 134 | |
|
135 | for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'), | |
|
136 | (1, 'repo_description'), (1, 'repo_enable_locking'), | |
|
137 | (1, 'repo_landing_rev'), (0, 'clone_uri'), | |
|
138 | (1, 'repo_private'), (1, 'repo_enable_statistics')]: | |
|
139 | attr = k | |
|
140 | if strip: | |
|
141 | attr = remove_prefix(k, 'repo_') | |
|
142 | ||
|
143 | defaults[k] = defaults[attr] | |
|
144 | ||
|
134 | 145 | # fill owner |
|
135 | 146 | if repo_info.user: |
|
136 | 147 | defaults.update({'user': repo_info.user.username}) |
@@ -151,12 +162,12 b' class RepoModel(BaseModel):' | |||
|
151 | 162 | |
|
152 | 163 | return defaults |
|
153 | 164 | |
|
154 |
def update(self, repo_name, |
|
|
165 | def update(self, org_repo_name, **kwargs): | |
|
155 | 166 | try: |
|
156 | cur_repo = self.get_by_repo_name(repo_name, cache=False) | |
|
167 | cur_repo = self.get_by_repo_name(org_repo_name, cache=False) | |
|
157 | 168 | |
|
158 | 169 | # update permissions |
|
159 |
for member, perm, member_type in |
|
|
170 | for member, perm, member_type in kwargs['perms_updates']: | |
|
160 | 171 | if member_type == 'user': |
|
161 | 172 | # this updates existing one |
|
162 | 173 | RepoModel().grant_user_permission( |
@@ -167,7 +178,7 b' class RepoModel(BaseModel):' | |||
|
167 | 178 | repo=cur_repo, group_name=member, perm=perm |
|
168 | 179 | ) |
|
169 | 180 | # set new permissions |
|
170 |
for member, perm, member_type in |
|
|
181 | for member, perm, member_type in kwargs['perms_new']: | |
|
171 | 182 | if member_type == 'user': |
|
172 | 183 | RepoModel().grant_user_permission( |
|
173 | 184 | repo=cur_repo, user=member, perm=perm |
@@ -177,26 +188,30 b' class RepoModel(BaseModel):' | |||
|
177 | 188 | repo=cur_repo, group_name=member, perm=perm |
|
178 | 189 | ) |
|
179 | 190 | |
|
180 | # update current repo | |
|
181 | for k, v in form_data.items(): | |
|
182 | if k == 'user': | |
|
183 | cur_repo.user = User.get_by_username(v) | |
|
184 | elif k == 'repo_name': | |
|
185 | pass | |
|
186 | elif k == 'repo_group': | |
|
187 | cur_repo.group = RepoGroup.get(v) | |
|
191 | if 'user' in kwargs: | |
|
192 | cur_repo.user = User.get_by_username(kwargs['user']) | |
|
193 | ||
|
194 | if 'repo_group' in kwargs: | |
|
195 | cur_repo.group = RepoGroup.get(kwargs['repo_group']) | |
|
188 | 196 | |
|
189 | else: | |
|
190 | setattr(cur_repo, k, v) | |
|
197 | for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'), | |
|
198 | (1, 'repo_description'), (1, 'repo_enable_locking'), | |
|
199 | (1, 'repo_landing_rev'), (0, 'clone_uri'), | |
|
200 | (1, 'repo_private'), (1, 'repo_enable_statistics')]: | |
|
201 | if k in kwargs: | |
|
202 | val = kwargs[k] | |
|
203 | if strip: | |
|
204 | k = remove_prefix(k, 'repo_') | |
|
205 | setattr(cur_repo, k, val) | |
|
191 | 206 | |
|
192 |
new_name = cur_repo.get_new_name( |
|
|
207 | new_name = cur_repo.get_new_name(kwargs['repo_name']) | |
|
193 | 208 | cur_repo.repo_name = new_name |
|
194 | 209 | |
|
195 | 210 | self.sa.add(cur_repo) |
|
196 | 211 | |
|
197 | if repo_name != new_name: | |
|
212 | if org_repo_name != new_name: | |
|
198 | 213 | # rename repository |
|
199 | self.__rename_repo(old=repo_name, new=new_name) | |
|
214 | self.__rename_repo(old=org_repo_name, new=new_name) | |
|
200 | 215 | |
|
201 | 216 | return cur_repo |
|
202 | 217 | except: |
@@ -566,9 +566,18 b" def ValidPerms(type_='repo'):" | |||
|
566 | 566 | def ValidSettings(): |
|
567 | 567 | class _validator(formencode.validators.FancyValidator): |
|
568 | 568 | def _to_python(self, value, state): |
|
569 |
# settings form |
|
|
570 | if 'user' in value: | |
|
571 | del value['user'] | |
|
569 | # settings form for users that are not admin | |
|
570 | # can't edit certain parameters, it's extra backup if they mangle | |
|
571 | # with forms | |
|
572 | ||
|
573 | forbidden_params = [ | |
|
574 | 'user', 'repo_type', 'repo_enable_locking', | |
|
575 | 'repo_enable_downloads', 'repo_enable_statistics' | |
|
576 | ] | |
|
577 | ||
|
578 | for param in forbidden_params: | |
|
579 | if param in value: | |
|
580 | del value[param] | |
|
572 | 581 | return value |
|
573 | 582 | |
|
574 | 583 | def validate_python(self, value, state): |
@@ -57,26 +57,26 b'' | |||
|
57 | 57 | <label for="landing_rev">${_('Landing revision')}:</label> |
|
58 | 58 | </div> |
|
59 | 59 | <div class="input"> |
|
60 | ${h.select('landing_rev','',c.landing_revs,class_="medium")} | |
|
60 | ${h.select('repo_landing_rev','',c.landing_revs,class_="medium")} | |
|
61 | 61 | <span class="help-block">${_('Default revision for files page, downloads, whoosh and readme')}</span> |
|
62 | 62 | </div> |
|
63 | 63 | </div> |
|
64 | 64 | <div class="field"> |
|
65 | 65 | <div class="label label-textarea"> |
|
66 | <label for="description">${_('Description')}:</label> | |
|
66 | <label for="repo_description">${_('Description')}:</label> | |
|
67 | 67 | </div> |
|
68 | 68 | <div class="textarea text-area editor"> |
|
69 | ${h.textarea('description')} | |
|
69 | ${h.textarea('repo_description')} | |
|
70 | 70 | <span class="help-block">${_('Keep it short and to the point. Use a README file for longer descriptions.')}</span> |
|
71 | 71 | </div> |
|
72 | 72 | </div> |
|
73 | 73 | |
|
74 | 74 | <div class="field"> |
|
75 | 75 | <div class="label label-checkbox"> |
|
76 | <label for="private">${_('Private repository')}:</label> | |
|
76 | <label for="repo_private">${_('Private repository')}:</label> | |
|
77 | 77 | </div> |
|
78 | 78 | <div class="checkboxes"> |
|
79 | ${h.checkbox('private',value="True")} | |
|
79 | ${h.checkbox('repo_private',value="True")} | |
|
80 | 80 | <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span> |
|
81 | 81 | </div> |
|
82 | 82 | </div> |
@@ -89,29 +89,7 b'' | |||
|
89 | 89 | <%include file="../admin/repos/repo_edit_perms.html"/> |
|
90 | 90 | </div> |
|
91 | 91 | </div> |
|
92 | ||
|
93 | <div class="field"> | |
|
94 | <div class="label"> | |
|
95 | <label for="">${_('Remove repo')}:</label> | |
|
96 | </div> | |
|
97 | <div class="checkboxes"> | |
|
98 | ${h.form(url('repo_settings_delete', repo_name=c.repo_info.repo_name),method='delete')} | |
|
99 | <div class=""> | |
|
100 | <div class="fields"> | |
|
101 | ${h.submit('remove_%s' % c.repo_info.repo_name,_('Remove this repository'),class_="ui-btn red",onclick="return confirm('"+_('Confirm to delete this repository')+"');")} | |
|
102 | </div> | |
|
103 | <div class="field" style="border:none;color:#888"> | |
|
104 | <ul> | |
|
105 | <li>${_('''This repository will be renamed in a special way in order to be unaccesible for RhodeCode and VCS systems. | |
|
106 | If you need fully delete it from file system please do it manually''')} | |
|
107 | </li> | |
|
108 | </ul> | |
|
109 | </div> | |
|
110 | </div> | |
|
111 | ${h.end_form()} | |
|
112 | </div> | |
|
113 | </div> | |
|
114 | ||
|
92 | ||
|
115 | 93 | <div class="buttons"> |
|
116 | 94 | ${h.submit('save',_('Save'),class_="ui-btn large")} |
|
117 | 95 | ${h.reset('reset',_('Reset'),class_="ui-btn large")} |
@@ -120,5 +98,35 b'' | |||
|
120 | 98 | </div> |
|
121 | 99 | ${h.end_form()} |
|
122 | 100 | </div> |
|
101 | ||
|
102 | <h3>${_('Delete repository')}</h3> | |
|
103 | <div class="form"> | |
|
104 | <!-- fields --> | |
|
105 | <div class="fields"> | |
|
106 | ||
|
107 | <div class="field"> | |
|
108 | <div class="label"> | |
|
109 | <label for="">${_('Remove repo')}:</label> | |
|
110 | </div> | |
|
111 | <div class="checkboxes"> | |
|
112 | ${h.form(url('repo_settings_delete', repo_name=c.repo_info.repo_name),method='delete')} | |
|
113 | <div class=""> | |
|
114 | <div class="fields"> | |
|
115 | ${h.submit('remove_%s' % c.repo_info.repo_name,_('Remove this repository'),class_="ui-btn red",onclick="return confirm('"+_('Confirm to delete this repository')+"');")} | |
|
116 | </div> | |
|
117 | <div class="field" style="border:none;color:#888"> | |
|
118 | <ul> | |
|
119 | <li>${_('''This repository will be renamed in a special way in order to be unaccesible for RhodeCode and VCS systems. | |
|
120 | If you need fully delete it from file system please do it manually''')} | |
|
121 | </li> | |
|
122 | </ul> | |
|
123 | </div> | |
|
124 | </div> | |
|
125 | ${h.end_form()} | |
|
126 | </div> | |
|
127 | </div> | |
|
128 | </div> | |
|
129 | </div> | |
|
130 | ||
|
123 | 131 | </div> |
|
124 | 132 | </%def> |
@@ -136,7 +136,7 b' class TestReposGroups(unittest.TestCase)' | |||
|
136 | 136 | form_data['repo_group'] = g1.group_id |
|
137 | 137 | form_data['perms_new'] = [] |
|
138 | 138 | form_data['perms_updates'] = [] |
|
139 | RepoModel().update(r.repo_name, form_data) | |
|
139 | RepoModel().update(r.repo_name, **form_data) | |
|
140 | 140 | self.assertEqual(r.repo_name, 'g1/john') |
|
141 | 141 | |
|
142 | 142 | self.__update_group(g1.group_id, 'g1', parent_id=g2.group_id) |
General Comments 0
You need to be logged in to leave comments.
Login now