Show More
@@ -0,0 +1,133 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | """ | |
|
3 | rhodecode.model.user_group | |
|
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
|
5 | ||
|
6 | users groups model for RhodeCode | |
|
7 | ||
|
8 | :created_on: Jan 25, 2011 | |
|
9 | :author: marcink | |
|
10 | :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com> | |
|
11 | :license: GPLv3, see COPYING for more details. | |
|
12 | """ | |
|
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 | |
|
15 | # the Free Software Foundation, either version 3 of the License, or | |
|
16 | # (at your option) any later version. | |
|
17 | # | |
|
18 | # This program is distributed in the hope that it will be useful, | |
|
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
21 | # GNU General Public License for more details. | |
|
22 | # | |
|
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/>. | |
|
25 | ||
|
26 | import os | |
|
27 | import logging | |
|
28 | import traceback | |
|
29 | ||
|
30 | from pylons.i18n.translation import _ | |
|
31 | ||
|
32 | from vcs.utils.lazy import LazyProperty | |
|
33 | ||
|
34 | from rhodecode.model import BaseModel | |
|
35 | from rhodecode.model.caching_query import FromCache | |
|
36 | from rhodecode.model.db import Group, RhodeCodeUi | |
|
37 | ||
|
38 | log = logging.getLogger(__name__) | |
|
39 | ||
|
40 | ||
|
41 | class ReposGroupModel(BaseModel): | |
|
42 | ||
|
43 | @LazyProperty | |
|
44 | def repos_path(self): | |
|
45 | """ | |
|
46 | Get's the repositories root path from database | |
|
47 | """ | |
|
48 | ||
|
49 | q = RhodeCodeUi.get_by_key('/').one() | |
|
50 | return q.ui_value | |
|
51 | ||
|
52 | def __create_group(self, group_name, parent_id): | |
|
53 | """ | |
|
54 | makes repositories group on filesystem | |
|
55 | ||
|
56 | :param repo_name: | |
|
57 | :param parent_id: | |
|
58 | """ | |
|
59 | ||
|
60 | if parent_id: | |
|
61 | parent_group_name = Group.get(parent_id).group_name | |
|
62 | else: | |
|
63 | parent_group_name = '' | |
|
64 | ||
|
65 | create_path = os.path.join(self.repos_path, parent_group_name, | |
|
66 | group_name) | |
|
67 | log.debug('creating new group in %s', create_path) | |
|
68 | ||
|
69 | if os.path.isdir(create_path): | |
|
70 | raise Exception('That directory already exists !') | |
|
71 | ||
|
72 | ||
|
73 | os.makedirs(create_path) | |
|
74 | ||
|
75 | ||
|
76 | def __rename_group(self, group_name): | |
|
77 | """ | |
|
78 | Renames a group on filesystem | |
|
79 | ||
|
80 | :param group_name: | |
|
81 | """ | |
|
82 | pass | |
|
83 | ||
|
84 | def __delete_group(self, group_name): | |
|
85 | """ | |
|
86 | Deletes a group from a filesystem | |
|
87 | ||
|
88 | :param group_name: | |
|
89 | """ | |
|
90 | pass | |
|
91 | ||
|
92 | def create(self, form_data): | |
|
93 | try: | |
|
94 | new_repos_group = Group() | |
|
95 | new_repos_group.group_name = form_data['repos_group_name'] | |
|
96 | new_repos_group.group_description = \ | |
|
97 | form_data['repos_group_description'] | |
|
98 | new_repos_group.group_parent_id = form_data['repos_group_parent'] | |
|
99 | ||
|
100 | self.sa.add(new_repos_group) | |
|
101 | ||
|
102 | self.__create_group(form_data['repos_group_name'], | |
|
103 | form_data['repos_group_parent']) | |
|
104 | ||
|
105 | self.sa.commit() | |
|
106 | except: | |
|
107 | log.error(traceback.format_exc()) | |
|
108 | self.sa.rollback() | |
|
109 | raise | |
|
110 | ||
|
111 | def update(self, repos_group_id, form_data): | |
|
112 | ||
|
113 | try: | |
|
114 | repos_group = Group.get(repos_group_id) | |
|
115 | ||
|
116 | ||
|
117 | ||
|
118 | self.sa.add(repos_group) | |
|
119 | self.sa.commit() | |
|
120 | except: | |
|
121 | log.error(traceback.format_exc()) | |
|
122 | self.sa.rollback() | |
|
123 | raise | |
|
124 | ||
|
125 | def delete(self, users_group_id): | |
|
126 | try: | |
|
127 | users_group = self.get(users_group_id, cache=False) | |
|
128 | self.sa.delete(users_group) | |
|
129 | self.sa.commit() | |
|
130 | except: | |
|
131 | log.error(traceback.format_exc()) | |
|
132 | self.sa.rollback() | |
|
133 | raise |
@@ -0,0 +1,64 b'' | |||
|
1 | ## -*- coding: utf-8 -*- | |
|
2 | <%inherit file="/base/base.html"/> | |
|
3 | ||
|
4 | <%def name="title()"> | |
|
5 | ${_('Add repos group')} - ${c.rhodecode_name} | |
|
6 | </%def> | |
|
7 | <%def name="breadcrumbs_links()"> | |
|
8 | ${h.link_to(_('Admin'),h.url('admin_home'))} | |
|
9 | » | |
|
10 | ${h.link_to(_('Repos groups'),h.url('repos_groups'))} | |
|
11 | » | |
|
12 | ${_('add new repos group')} | |
|
13 | </%def> | |
|
14 | ||
|
15 | <%def name="page_nav()"> | |
|
16 | ${self.menu('admin')} | |
|
17 | </%def> | |
|
18 | ||
|
19 | <%def name="main()"> | |
|
20 | <div class="box"> | |
|
21 | <!-- box / title --> | |
|
22 | <div class="title"> | |
|
23 | ${self.breadcrumbs()} | |
|
24 | </div> | |
|
25 | <!-- end box / title --> | |
|
26 | ${h.form(url('repos_groups'))} | |
|
27 | <div class="form"> | |
|
28 | <!-- fields --> | |
|
29 | <div class="fields"> | |
|
30 | <div class="field"> | |
|
31 | <div class="label"> | |
|
32 | <label for="users_group_name">${_('Group name')}:</label> | |
|
33 | </div> | |
|
34 | <div class="input"> | |
|
35 | ${h.text('repos_group_name',class_='medium')} | |
|
36 | </div> | |
|
37 | </div> | |
|
38 | ||
|
39 | <div class="field"> | |
|
40 | <div class="label label-textarea"> | |
|
41 | <label for="description">${_('Description')}:</label> | |
|
42 | </div> | |
|
43 | <div class="textarea text-area editor"> | |
|
44 | ${h.textarea('repos_group_description',cols=23,rows=5,class_="medium")} | |
|
45 | </div> | |
|
46 | </div> | |
|
47 | ||
|
48 | <div class="field"> | |
|
49 | <div class="label"> | |
|
50 | <label for="repo_group">${_('Group parent')}:</label> | |
|
51 | </div> | |
|
52 | <div class="input"> | |
|
53 | ${h.select('repos_group_parent','',c.repo_groups,class_="medium")} | |
|
54 | </div> | |
|
55 | </div> | |
|
56 | ||
|
57 | <div class="buttons"> | |
|
58 | ${h.submit('save','save',class_="ui-button")} | |
|
59 | </div> | |
|
60 | </div> | |
|
61 | </div> | |
|
62 | ${h.end_form()} | |
|
63 | </div> | |
|
64 | </%def> No newline at end of file |
@@ -0,0 +1,68 b'' | |||
|
1 | ## -*- coding: utf-8 -*- | |
|
2 | <%inherit file="/base/base.html"/> | |
|
3 | ||
|
4 | <%def name="title()"> | |
|
5 | ${_('Repositories groups administration')} - ${c.rhodecode_name} | |
|
6 | </%def> | |
|
7 | ||
|
8 | ||
|
9 | <%def name="breadcrumbs_links()"> | |
|
10 | ${h.link_to(_('Admin'),h.url('admin_home'))} » ${_('Repositories')} | |
|
11 | </%def> | |
|
12 | <%def name="page_nav()"> | |
|
13 | ${self.menu('admin')} | |
|
14 | </%def> | |
|
15 | <%def name="main()"> | |
|
16 | <div class="box"> | |
|
17 | <!-- box / title --> | |
|
18 | <div class="title"> | |
|
19 | ${self.breadcrumbs()} | |
|
20 | <ul class="links"> | |
|
21 | <li> | |
|
22 | <span>${h.link_to(u'ADD NEW GROUP',h.url('new_repos_group'))}</span> | |
|
23 | </li> | |
|
24 | </ul> | |
|
25 | </div> | |
|
26 | <!-- end box / title --> | |
|
27 | <div class="table"> | |
|
28 | % if c.groups: | |
|
29 | <table class="table_disp"> | |
|
30 | ||
|
31 | <thead> | |
|
32 | <tr> | |
|
33 | <th class="left"><a href="#">${_('Group name')}</a></th> | |
|
34 | <th class="left"><a href="#">${_('Description')}</a></th> | |
|
35 | <th class="left"><a href="#">${_('Number of repositories')}</a></th> | |
|
36 | <th class="left">${_('action')}</th> | |
|
37 | </tr> | |
|
38 | </thead> | |
|
39 | ||
|
40 | ## REPO GROUPS | |
|
41 | ||
|
42 | % for gr in c.groups: | |
|
43 | <tr> | |
|
44 | <td> | |
|
45 | <div style="white-space: nowrap"> | |
|
46 | <img class="icon" alt="${_('Repositories group')}" src="${h.url('/images/icons/database_link.png')}"/> | |
|
47 | ${h.link_to(h.literal(' » '.join([g.group_name for g in gr.parents+[gr]])),url('edit_repos_group',id=gr.group_id))} | |
|
48 | </div> | |
|
49 | </td> | |
|
50 | <td>${gr.group_description}</td> | |
|
51 | <td><b>${gr.repositories.count()}</b></td> | |
|
52 | <td> | |
|
53 | ${h.form(url('repos_group', id=gr.group_id),method='delete')} | |
|
54 | ${h.submit('remove_%s' % gr.group_name,'delete',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this group');")} | |
|
55 | ${h.end_form()} | |
|
56 | </td> | |
|
57 | </tr> | |
|
58 | % endfor | |
|
59 | ||
|
60 | </table> | |
|
61 | % else: | |
|
62 | {_('There are no repositories groups yet')} | |
|
63 | % endif | |
|
64 | ||
|
65 | </div> | |
|
66 | </div> | |
|
67 | ||
|
68 | </%def> |
@@ -74,6 +74,8 b' class ReposController(BaseController):' | |||
|
74 | 74 | |
|
75 | 75 | c.repo_groups.extend([(x.group_id, parents_link(x)) for \ |
|
76 | 76 | x in self.sa.query(Group).all()]) |
|
77 | c.repo_groups = sorted(c.repo_groups, | |
|
78 | key=lambda t: t[1].split('»')[0]) | |
|
77 | 79 | c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) |
|
78 | 80 | c.users_array = repo_model.get_users_js() |
|
79 | 81 | c.users_groups_array = repo_model.get_users_groups_js() |
@@ -1,11 +1,21 b'' | |||
|
1 | 1 | import logging |
|
2 | import traceback | |
|
3 | import formencode | |
|
4 | ||
|
5 | from formencode import htmlfill | |
|
2 | 6 | from operator import itemgetter |
|
3 | 7 | |
|
4 | 8 | from pylons import request, response, session, tmpl_context as c, url |
|
5 | 9 | from pylons.controllers.util import abort, redirect |
|
10 | from pylons.i18n.translation import _ | |
|
6 | 11 | |
|
12 | from rhodecode.lib import helpers as h | |
|
13 | from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \ | |
|
14 | HasPermissionAnyDecorator | |
|
7 | 15 | from rhodecode.lib.base import BaseController, render |
|
8 | 16 | from rhodecode.model.db import Group |
|
17 | from rhodecode.model.repos_group import ReposGroupModel | |
|
18 | from rhodecode.model.forms import ReposGroupForm | |
|
9 | 19 | |
|
10 | 20 | log = logging.getLogger(__name__) |
|
11 | 21 | |
@@ -16,18 +26,73 b' class ReposGroupsController(BaseControll' | |||
|
16 | 26 | # file has a resource setup: |
|
17 | 27 | # map.resource('repos_group', 'repos_groups') |
|
18 | 28 | |
|
29 | def __load_defaults(self): | |
|
30 | ||
|
31 | c.repo_groups = [('', '')] | |
|
32 | parents_link = lambda k: h.literal('»'.join( | |
|
33 | map(lambda k: k.group_name, | |
|
34 | k.parents + [k]) | |
|
35 | ) | |
|
36 | ) | |
|
37 | ||
|
38 | c.repo_groups.extend([(x.group_id, parents_link(x)) for \ | |
|
39 | x in self.sa.query(Group).all()]) | |
|
40 | ||
|
41 | c.repo_groups = sorted(c.repo_groups, | |
|
42 | key=lambda t: t[1].split('»')[0]) | |
|
43 | c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) | |
|
44 | ||
|
45 | @LoginRequired() | |
|
46 | def __before__(self): | |
|
47 | super(ReposGroupsController, self).__before__() | |
|
48 | ||
|
49 | @HasPermissionAnyDecorator('hg.admin') | |
|
19 | 50 | def index(self, format='html'): |
|
20 | 51 | """GET /repos_groups: All items in the collection""" |
|
21 | 52 | # url('repos_groups') |
|
22 | 53 | |
|
54 | sk = lambda g:g.parents[0].group_name if g.parents else g.group_name | |
|
55 | c.groups = sorted(Group.query().all(), key=sk) | |
|
56 | return render('admin/repos_groups/repos_groups_show.html') | |
|
57 | ||
|
58 | @HasPermissionAnyDecorator('hg.admin') | |
|
23 | 59 | def create(self): |
|
24 | 60 | """POST /repos_groups: Create a new item""" |
|
25 | 61 | # url('repos_groups') |
|
62 | self.__load_defaults() | |
|
63 | repos_group_model = ReposGroupModel() | |
|
64 | repos_group_form = ReposGroupForm(available_groups= | |
|
65 | c.repo_groups_choices)() | |
|
66 | try: | |
|
67 | form_result = repos_group_form.to_python(dict(request.POST)) | |
|
68 | repos_group_model.create(form_result) | |
|
69 | h.flash(_('created repos group %s') \ | |
|
70 | % form_result['repos_group_name'], category='success') | |
|
71 | #TODO: in futureaction_logger(, '', '', '', self.sa) | |
|
72 | except formencode.Invalid, errors: | |
|
26 | 73 | |
|
74 | return htmlfill.render( | |
|
75 | render('admin/repos_groups/repos_groups_add.html'), | |
|
76 | defaults=errors.value, | |
|
77 | errors=errors.error_dict or {}, | |
|
78 | prefix_error=False, | |
|
79 | encoding="UTF-8") | |
|
80 | except Exception: | |
|
81 | log.error(traceback.format_exc()) | |
|
82 | h.flash(_('error occurred during creation of repos group %s') \ | |
|
83 | % request.POST.get('repos_group_name'), category='error') | |
|
84 | ||
|
85 | return redirect(url('repos_groups')) | |
|
86 | ||
|
87 | ||
|
88 | @HasPermissionAnyDecorator('hg.admin') | |
|
27 | 89 | def new(self, format='html'): |
|
28 | 90 | """GET /repos_groups/new: Form to create a new item""" |
|
29 | 91 | # url('new_repos_group') |
|
92 | self.__load_defaults() | |
|
93 | return render('admin/repos_groups/repos_groups_add.html') | |
|
30 | 94 | |
|
95 | @HasPermissionAnyDecorator('hg.admin') | |
|
31 | 96 | def update(self, id): |
|
32 | 97 | """PUT /repos_groups/id: Update an existing item""" |
|
33 | 98 | # Forms posted to this method should contain a hidden field: |
@@ -37,6 +102,7 b' class ReposGroupsController(BaseControll' | |||
|
37 | 102 | # method='put') |
|
38 | 103 | # url('repos_group', id=ID) |
|
39 | 104 | |
|
105 | @HasPermissionAnyDecorator('hg.admin') | |
|
40 | 106 | def delete(self, id): |
|
41 | 107 | """DELETE /repos_groups/id: Delete an existing item""" |
|
42 | 108 | # Forms posted to this method should contain a hidden field: |
@@ -88,6 +154,7 b' class ReposGroupsController(BaseControll' | |||
|
88 | 154 | |
|
89 | 155 | return render('admin/repos_groups/repos_groups.html') |
|
90 | 156 | |
|
157 | @HasPermissionAnyDecorator('hg.admin') | |
|
91 | 158 | def edit(self, id, format='html'): |
|
92 | 159 | """GET /repos_groups/id/edit: Form to edit an existing item""" |
|
93 | 160 | # url('edit_repos_group', id=ID) |
@@ -332,6 +332,8 b' class SettingsController(BaseController)' | |||
|
332 | 332 | |
|
333 | 333 | c.repo_groups.extend([(x.group_id, parents_link(x)) for \ |
|
334 | 334 | x in self.sa.query(Group).all()]) |
|
335 | c.repo_groups = sorted(c.repo_groups, | |
|
336 | key=lambda t: t[1].split('»')[0]) | |
|
335 | 337 | c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) |
|
336 | 338 | |
|
337 | 339 | new_repo = request.GET.get('repo', '') |
@@ -66,8 +66,7 b' class HomeController(BaseController):' | |||
|
66 | 66 | c.repo_cnt = len(c.repos_list) |
|
67 | 67 | |
|
68 | 68 | |
|
69 | c.groups = self.sa.query(Group)\ | |
|
70 | .filter(Group.group_parent_id == None).all() | |
|
69 | c.groups = Group.query().filter(Group.group_parent_id == None).all() | |
|
71 | 70 | |
|
72 | 71 | |
|
73 | 72 | return render('/index.html') |
@@ -107,6 +107,11 b' class RhodeCodeUi(Base):' | |||
|
107 | 107 | ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) |
|
108 | 108 | |
|
109 | 109 | |
|
110 | @classmethod | |
|
111 | def get_by_key(cls, key): | |
|
112 | return Session.query(cls).filter(cls.ui_key == key) | |
|
113 | ||
|
114 | ||
|
110 | 115 | class User(Base): |
|
111 | 116 | __tablename__ = 'users' |
|
112 | 117 | __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True}) |
@@ -296,7 +301,7 b' class Repository(Base):' | |||
|
296 | 301 | |
|
297 | 302 | class Group(Base): |
|
298 | 303 | __tablename__ = 'groups' |
|
299 | __table_args__ = (UniqueConstraint('group_name'), {'useexisting':True},) | |
|
304 | __table_args__ = (UniqueConstraint('group_name', 'group_parent_id'), {'useexisting':True},) | |
|
300 | 305 | __mapper_args__ = {'order_by':'group_name'} |
|
301 | 306 | |
|
302 | 307 | group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) |
@@ -35,7 +35,6 b' from webhelpers.pylonslib.secure_form im' | |||
|
35 | 35 | from rhodecode.lib.utils import repo_name_slug |
|
36 | 36 | from rhodecode.lib.auth import authenticate, get_crypt_password |
|
37 | 37 | from rhodecode.lib.exceptions import LdapImportError |
|
38 | from rhodecode.model import meta | |
|
39 | 38 | from rhodecode.model.user import UserModel |
|
40 | 39 | from rhodecode.model.repo import RepoModel |
|
41 | 40 | from rhodecode.model.db import User, UsersGroup, Group |
@@ -117,6 +116,27 b' def ValidUsersGroup(edit, old_data):' | |||
|
117 | 116 | return _ValidUsersGroup |
|
118 | 117 | |
|
119 | 118 | |
|
119 | def ValidReposGroup(edit, old_data): | |
|
120 | ||
|
121 | class _ValidReposGroup(formencode.validators.FancyValidator): | |
|
122 | ||
|
123 | def validate_python(self, value, state): | |
|
124 | #TODO WRITE VALIDATIONS | |
|
125 | group_name = value.get('repos_group_name') | |
|
126 | parent_id = value.get('repos_group_parent') | |
|
127 | ||
|
128 | # slugify repo group just in case :) | |
|
129 | slug = repo_name_slug(group_name) | |
|
130 | ||
|
131 | # check filesystem | |
|
132 | gr = Group.query().filter(Group.group_name == slug)\ | |
|
133 | .filter(Group.group_parent_id == parent_id).scalar() | |
|
134 | ||
|
135 | if gr: | |
|
136 | e_dict = {'repos_group_name':_('This group already exists')} | |
|
137 | raise formencode.Invalid('', value, state, | |
|
138 | error_dict=e_dict) | |
|
139 | return _ValidReposGroup | |
|
120 | 140 | |
|
121 | 141 | class ValidPassword(formencode.validators.FancyValidator): |
|
122 | 142 | |
@@ -193,17 +213,13 b' class ValidAuth(formencode.validators.Fa' | |||
|
193 | 213 | class ValidRepoUser(formencode.validators.FancyValidator): |
|
194 | 214 | |
|
195 | 215 | def to_python(self, value, state): |
|
196 | sa = meta.Session() | |
|
197 | 216 | try: |
|
198 |
self.user_db = |
|
|
217 | self.user_db = User.query()\ | |
|
199 | 218 | .filter(User.active == True)\ |
|
200 | 219 | .filter(User.username == value).one() |
|
201 | 220 | except Exception: |
|
202 | 221 | raise formencode.Invalid(_('This username is not valid'), |
|
203 | 222 | value, state) |
|
204 | finally: | |
|
205 | meta.Session.remove() | |
|
206 | ||
|
207 | 223 | return value |
|
208 | 224 | |
|
209 | 225 | def ValidRepoName(edit, old_data): |
@@ -222,6 +238,7 b' def ValidRepoName(edit, old_data):' | |||
|
222 | 238 | gr = Group.get(value.get('repo_group')) |
|
223 | 239 | group_path = gr.full_path |
|
224 | 240 | # value needs to be aware of group name |
|
241 | # it has to use '/' | |
|
225 | 242 | repo_name_full = group_path + '/' + repo_name |
|
226 | 243 | else: |
|
227 | 244 | group_path = '' |
@@ -250,13 +267,13 b' def ValidRepoName(edit, old_data):' | |||
|
250 | 267 | |
|
251 | 268 | return _ValidRepoName |
|
252 | 269 | |
|
253 |
def Slugify |
|
|
254 |
class _Slugify |
|
|
270 | def SlugifyName(): | |
|
271 | class _SlugifyName(formencode.validators.FancyValidator): | |
|
255 | 272 | |
|
256 | 273 | def to_python(self, value, state): |
|
257 | 274 | return repo_name_slug(value) |
|
258 | 275 | |
|
259 |
return _Slugify |
|
|
276 | return _SlugifyName | |
|
260 | 277 | |
|
261 | 278 | def ValidCloneUri(): |
|
262 | 279 | from mercurial.httprepo import httprepository, httpsrepository |
@@ -331,15 +348,14 b' class ValidPerms(formencode.validators.F' | |||
|
331 | 348 | value['perms_new'] = perms_new |
|
332 | 349 | |
|
333 | 350 | #update permissions |
|
334 | sa = meta.Session | |
|
335 | 351 | for k, v, t in perms_new: |
|
336 | 352 | try: |
|
337 | 353 | if t is 'user': |
|
338 |
self.user_db = |
|
|
354 | self.user_db = User.query()\ | |
|
339 | 355 | .filter(User.active == True)\ |
|
340 | 356 | .filter(User.username == k).one() |
|
341 | 357 | if t is 'users_group': |
|
342 |
self.user_db = |
|
|
358 | self.user_db = UsersGroup.query()\ | |
|
343 | 359 | .filter(UsersGroup.users_group_active == True)\ |
|
344 | 360 | .filter(UsersGroup.users_group_name == k).one() |
|
345 | 361 | |
@@ -373,15 +389,11 b' def UniqSystemEmail(old_data):' | |||
|
373 | 389 | def to_python(self, value, state): |
|
374 | 390 | value = value.lower() |
|
375 | 391 | if old_data.get('email') != value: |
|
376 | sa = meta.Session() | |
|
377 |
|
|
|
378 | user = sa.query(User).filter(User.email == value).scalar() | |
|
379 | if user: | |
|
380 | raise formencode.Invalid(_("This e-mail address is already taken") , | |
|
381 | value, state) | |
|
382 | finally: | |
|
383 | meta.Session.remove() | |
|
384 | ||
|
392 | user = User.query().filter(User.email == value).scalar() | |
|
393 | if user: | |
|
394 | raise formencode.Invalid( | |
|
395 | _("This e-mail address is already taken"), | |
|
396 | value, state) | |
|
385 | 397 | return value |
|
386 | 398 | |
|
387 | 399 | return _UniqSystemEmail |
@@ -389,14 +401,10 b' def UniqSystemEmail(old_data):' | |||
|
389 | 401 | class ValidSystemEmail(formencode.validators.FancyValidator): |
|
390 | 402 | def to_python(self, value, state): |
|
391 | 403 | value = value.lower() |
|
392 | sa = meta.Session | |
|
393 | try: | |
|
394 | user = sa.query(User).filter(User.email == value).scalar() | |
|
395 | if user is None: | |
|
396 | raise formencode.Invalid(_("This e-mail address doesn't exist.") , | |
|
397 | value, state) | |
|
398 | finally: | |
|
399 | meta.Session.remove() | |
|
404 | user = User.query().filter(User.email == value).scalar() | |
|
405 | if user is None: | |
|
406 | raise formencode.Invalid(_("This e-mail address doesn't exist.") , | |
|
407 | value, state) | |
|
400 | 408 | |
|
401 | 409 | return value |
|
402 | 410 | |
@@ -489,6 +497,23 b' def UsersGroupForm(edit=False, old_data=' | |||
|
489 | 497 | |
|
490 | 498 | return _UsersGroupForm |
|
491 | 499 | |
|
500 | def ReposGroupForm(edit=False, old_data={}, available_groups=[]): | |
|
501 | class _ReposGroupForm(formencode.Schema): | |
|
502 | allow_extra_fields = True | |
|
503 | filter_extra_fields = True | |
|
504 | ||
|
505 | repos_group_name = All(UnicodeString(strip=True, min=1, not_empty=True), | |
|
506 | SlugifyName()) | |
|
507 | repos_group_description = UnicodeString(strip=True, min=1, | |
|
508 | not_empty=True) | |
|
509 | repos_group_parent = OneOf(available_groups, hideList=False, | |
|
510 | testValueList=True, | |
|
511 | if_missing=None, not_empty=False) | |
|
512 | ||
|
513 | chained_validators = [ValidReposGroup(edit, old_data)] | |
|
514 | ||
|
515 | return _ReposGroupForm | |
|
516 | ||
|
492 | 517 | def RegisterForm(edit=False, old_data={}): |
|
493 | 518 | class _RegisterForm(formencode.Schema): |
|
494 | 519 | allow_extra_fields = True |
@@ -519,7 +544,7 b' def RepoForm(edit=False, old_data={}, su' | |||
|
519 | 544 | allow_extra_fields = True |
|
520 | 545 | filter_extra_fields = False |
|
521 | 546 | repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), |
|
522 |
Slugify |
|
|
547 | SlugifyName()) | |
|
523 | 548 | clone_uri = All(UnicodeString(strip=True, min=1, not_empty=False), |
|
524 | 549 | ValidCloneUri()()) |
|
525 | 550 | repo_group = OneOf(repo_groups, hideList=True) |
@@ -541,7 +566,7 b' def RepoForkForm(edit=False, old_data={}' | |||
|
541 | 566 | allow_extra_fields = True |
|
542 | 567 | filter_extra_fields = False |
|
543 | 568 | fork_name = All(UnicodeString(strip=True, min=1, not_empty=True), |
|
544 |
Slugify |
|
|
569 | SlugifyName()) | |
|
545 | 570 | description = UnicodeString(strip=True, min=1, not_empty=True) |
|
546 | 571 | private = StringBoolean(if_missing=False) |
|
547 | 572 | repo_type = All(ValidForkType(old_data), OneOf(supported_backends)) |
@@ -552,7 +577,7 b' def RepoSettingsForm(edit=False, old_dat' | |||
|
552 | 577 | allow_extra_fields = True |
|
553 | 578 | filter_extra_fields = False |
|
554 | 579 | repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), |
|
555 |
Slugify |
|
|
580 | SlugifyName()) | |
|
556 | 581 | description = UnicodeString(strip=True, min=1, not_empty=True) |
|
557 | 582 | private = StringBoolean(if_missing=False) |
|
558 | 583 |
@@ -477,6 +477,13 b' margin:0;' | |||
|
477 | 477 | padding:12px 9px 7px 24px; |
|
478 | 478 | } |
|
479 | 479 | |
|
480 | #header #header-inner #quick li ul li a.repos_groups,#header #header-inner #quick li ul li a.repos_groups:hover { | |
|
481 | background:url("../images/icons/database_link.png") no-repeat scroll 4px 9px #FFF; | |
|
482 | width:167px; | |
|
483 | margin:0; | |
|
484 | padding:12px 9px 7px 24px; | |
|
485 | } | |
|
486 | ||
|
480 | 487 | #header #header-inner #quick li ul li a.users,#header #header-inner #quick li ul li a.users:hover { |
|
481 | 488 | background:#FFF url("../images/icons/user_edit.png") no-repeat 4px 9px; |
|
482 | 489 | width:167px; |
@@ -26,7 +26,6 b'' | |||
|
26 | 26 | </div> |
|
27 | 27 | <div class="input"> |
|
28 | 28 | ${h.select('repo_group','',c.repo_groups,class_="medium")} |
|
29 | <span>${h.link_to(_('add new group'),h.url(''))}</span> | |
|
30 | 29 | </div> |
|
31 | 30 | </div> |
|
32 | 31 | <div class="field"> |
@@ -49,7 +49,6 b'' | |||
|
49 | 49 | </div> |
|
50 | 50 | <div class="input"> |
|
51 | 51 | ${h.select('repo_group','',c.repo_groups,class_="medium")} |
|
52 | <span>${h.link_to(_('add new group'),h.url(''))}</span> | |
|
53 | 52 | </div> |
|
54 | 53 | </div> |
|
55 | 54 | <div class="field"> |
@@ -322,6 +322,7 b'' | |||
|
322 | 322 | <ul> |
|
323 | 323 | <li>${h.link_to(_('journal'),h.url('admin_home'),class_='journal')}</li> |
|
324 | 324 | <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li> |
|
325 | <li>${h.link_to(_('repositories groups'),h.url('repos_groups'),class_='repos_groups')}</li> | |
|
325 | 326 | <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li> |
|
326 | 327 | <li>${h.link_to(_('users groups'),h.url('users_groups'),class_='groups')}</li> |
|
327 | 328 | <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li> |
General Comments 0
You need to be logged in to leave comments.
Login now