Show More
@@ -80,6 +80,10 b' def make_map(config):' | |||
|
80 | 80 | m.connect('repo_cache', "/repos_cache/{repo_name:.*}", |
|
81 | 81 | action="repo_cache", conditions=dict(method=["DELETE"], |
|
82 | 82 | function=check_repo)) |
|
83 | ||
|
84 | #ADMIN USER REST ROUTES | |
|
85 | map.resource('user', 'users', controller='admin/users', path_prefix='/_admin') | |
|
86 | ||
|
83 | 87 | #ADMIN USER REST ROUTES |
|
84 | 88 | map.resource('users_group', 'users_groups', controller='admin/users_groups', path_prefix='/_admin') |
|
85 | 89 |
@@ -41,8 +41,9 b' from rhodecode.lib.auth import LoginRequ' | |||
|
41 | 41 | from rhodecode.lib.base import BaseController, render |
|
42 | 42 | |
|
43 | 43 | from rhodecode.model.db import User, UsersGroup |
|
44 | from rhodecode.model.forms import UserForm | |
|
44 | from rhodecode.model.forms import UserForm, UsersGroupForm | |
|
45 | 45 | from rhodecode.model.user import UserModel |
|
46 | from rhodecode.model.users_group import UsersGroupModel | |
|
46 | 47 | |
|
47 | 48 | log = logging.getLogger(__name__) |
|
48 | 49 | |
@@ -63,16 +64,38 b' class UsersGroupsController(BaseControll' | |||
|
63 | 64 | def index(self, format='html'): |
|
64 | 65 | """GET /users_groups: All items in the collection""" |
|
65 | 66 | # url('users_groups') |
|
66 |
c.users_groups_list = |
|
|
67 | c.users_groups_list = self.sa.query(UsersGroup).all() | |
|
67 | 68 | return render('admin/users_groups/users_groups.html') |
|
68 | 69 | |
|
69 | 70 | def create(self): |
|
70 | 71 | """POST /users_groups: Create a new item""" |
|
71 | 72 | # url('users_groups') |
|
73 | users_group_model = UsersGroupModel() | |
|
74 | users_group_form = UsersGroupForm()() | |
|
75 | try: | |
|
76 | form_result = users_group_form.to_python(dict(request.POST)) | |
|
77 | users_group_model.create(form_result) | |
|
78 | h.flash(_('created users group %s') % form_result['users_group_name'], | |
|
79 | category='success') | |
|
80 | #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa) | |
|
81 | except formencode.Invalid, errors: | |
|
82 | return htmlfill.render( | |
|
83 | render('admin/users_groups/users_group_add.html'), | |
|
84 | defaults=errors.value, | |
|
85 | errors=errors.error_dict or {}, | |
|
86 | prefix_error=False, | |
|
87 | encoding="UTF-8") | |
|
88 | except Exception: | |
|
89 | log.error(traceback.format_exc()) | |
|
90 | h.flash(_('error occurred during creation of users group %s') \ | |
|
91 | % request.POST.get('users_group_name'), category='error') | |
|
92 | ||
|
93 | return redirect(url('users_groups')) | |
|
72 | 94 | |
|
73 | 95 | def new(self, format='html'): |
|
74 | 96 | """GET /users_groups/new: Form to create a new item""" |
|
75 | 97 | # url('new_users_group') |
|
98 | return render('admin/users_groups/users_group_add.html') | |
|
76 | 99 | |
|
77 | 100 | def update(self, id): |
|
78 | 101 | """PUT /users_groups/id: Update an existing item""" |
@@ -158,19 +158,18 b' class UsersGroup(Base, BaseModel):' | |||
|
158 | 158 | __tablename__ = 'users_groups' |
|
159 | 159 | __table_args__ = {'useexisting':True} |
|
160 | 160 | |
|
161 |
user_group_id = Column("users_group |
|
|
162 | user_group_name = Column("user_group_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) | |
|
163 | ||
|
161 | users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) | |
|
162 | users_group_name = Column("users_group_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) | |
|
163 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) | |
|
164 | 164 | |
|
165 | 165 | members = relation('UsersGroupMember') |
|
166 | 166 | |
|
167 | ||
|
168 | 167 | class UsersGroupMember(Base, BaseModel): |
|
169 | 168 | __tablename__ = 'users_groups_members' |
|
170 | 169 | __table_args__ = {'useexisting':True} |
|
171 | 170 | |
|
172 |
user_group |
|
|
173 |
user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group |
|
|
171 | users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) | |
|
172 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
|
174 | 173 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) |
|
175 | 174 | |
|
176 | 175 | user = relation('User') |
@@ -257,7 +256,7 b' class UsersGroupToPerm(Base, BaseModel):' | |||
|
257 | 256 | __tablename__ = 'users_group_to_perm' |
|
258 | 257 | __table_args__ = (UniqueConstraint('users_group_id', 'permission_id'), {'useexisting':True}) |
|
259 | 258 | users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) |
|
260 |
users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group |
|
|
259 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
|
261 | 260 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
262 | 261 | |
|
263 | 262 | users_group = relation('UsersGroup') |
@@ -36,6 +36,7 b' from rhodecode.lib.exceptions import Lda' | |||
|
36 | 36 | from rhodecode.model import meta |
|
37 | 37 | from rhodecode.model.user import UserModel |
|
38 | 38 | from rhodecode.model.repo import RepoModel |
|
39 | from rhodecode.model.users_group import UsersGroupModel | |
|
39 | 40 | from rhodecode.model.db import User |
|
40 | 41 | from rhodecode import BACKENDS |
|
41 | 42 | |
@@ -88,6 +89,38 b' def ValidUsername(edit, old_data):' | |||
|
88 | 89 | |
|
89 | 90 | return _ValidUsername |
|
90 | 91 | |
|
92 | ||
|
93 | ||
|
94 | def ValidUsersGroup(edit, old_data): | |
|
95 | ||
|
96 | class _ValidUsersGroup(formencode.validators.FancyValidator): | |
|
97 | ||
|
98 | def validate_python(self, value, state): | |
|
99 | if value in ['default']: | |
|
100 | raise formencode.Invalid(_('Invalid group name'), value, state) | |
|
101 | #check if group is unique | |
|
102 | old_un = None | |
|
103 | if edit: | |
|
104 | old_un = UserModel().get(old_data.get('users_group_id')).username | |
|
105 | ||
|
106 | if old_un != value or not edit: | |
|
107 | if UsersGroupModel().get_by_groupname(value, cache=False, | |
|
108 | case_insensitive=True): | |
|
109 | raise formencode.Invalid(_('This users group already exists') , | |
|
110 | value, state) | |
|
111 | ||
|
112 | ||
|
113 | if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None: | |
|
114 | raise formencode.Invalid(_('Group name may only contain ' | |
|
115 | 'alphanumeric characters underscores, ' | |
|
116 | 'periods or dashes and must begin with ' | |
|
117 | 'alphanumeric character'), | |
|
118 | value, state) | |
|
119 | ||
|
120 | return _ValidUsersGroup | |
|
121 | ||
|
122 | ||
|
123 | ||
|
91 | 124 | class ValidPassword(formencode.validators.FancyValidator): |
|
92 | 125 | |
|
93 | 126 | def to_python(self, value, state): |
@@ -368,6 +401,19 b' def UserForm(edit=False, old_data={}):' | |||
|
368 | 401 | |
|
369 | 402 | return _UserForm |
|
370 | 403 | |
|
404 | ||
|
405 | def UsersGroupForm(edit=False, old_data={}): | |
|
406 | class _UsersGroupForm(formencode.Schema): | |
|
407 | allow_extra_fields = True | |
|
408 | filter_extra_fields = True | |
|
409 | ||
|
410 | users_group_name = All(UnicodeString(strip=True, min=1, not_empty=True), | |
|
411 | ValidUsersGroup(edit, old_data)) | |
|
412 | ||
|
413 | users_group_active = StringBoolean(if_missing=False) | |
|
414 | ||
|
415 | return _UsersGroupForm | |
|
416 | ||
|
371 | 417 | def RegisterForm(edit=False, old_data={}): |
|
372 | 418 | class _RegisterForm(formencode.Schema): |
|
373 | 419 | allow_extra_fields = True |
@@ -24,3 +24,56 b'' | |||
|
24 | 24 | # along with this program; if not, write to the Free Software |
|
25 | 25 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
26 | 26 | # MA 02110-1301, USA. |
|
27 | ||
|
28 | import logging | |
|
29 | import traceback | |
|
30 | ||
|
31 | from pylons.i18n.translation import _ | |
|
32 | ||
|
33 | from rhodecode.model import BaseModel | |
|
34 | from rhodecode.model.caching_query import FromCache | |
|
35 | from rhodecode.model.db import UsersGroup | |
|
36 | ||
|
37 | from rhodecode.lib.exceptions import DefaultUserException, UserOwnsReposException | |
|
38 | ||
|
39 | from sqlalchemy.exc import DatabaseError | |
|
40 | ||
|
41 | log = logging.getLogger(__name__) | |
|
42 | ||
|
43 | ||
|
44 | class UsersGroupModel(BaseModel): | |
|
45 | ||
|
46 | def get(self, users_group_id, cache=False): | |
|
47 | users_group = self.sa.query(UsersGroup) | |
|
48 | if cache: | |
|
49 | users_group = users_group.options(FromCache("sql_cache_short", | |
|
50 | "get_users_group_%s" % users_group_id)) | |
|
51 | return users_group.get(users_group_id) | |
|
52 | ||
|
53 | ||
|
54 | def get_by_groupname(self, users_group_name, cache=False, case_insensitive=False): | |
|
55 | ||
|
56 | if case_insensitive: | |
|
57 | user = self.sa.query(UsersGroup)\ | |
|
58 | .filter(UsersGroup.users_group_name.ilike(users_group_name)) | |
|
59 | else: | |
|
60 | user = self.sa.query(UsersGroup)\ | |
|
61 | .filter(UsersGroup.users_group_name == users_group_name) | |
|
62 | if cache: | |
|
63 | user = user.options(FromCache("sql_cache_short", | |
|
64 | "get_user_%s" % users_group_name)) | |
|
65 | return user.scalar() | |
|
66 | ||
|
67 | def create(self, form_data): | |
|
68 | try: | |
|
69 | new_users_group = UsersGroup() | |
|
70 | for k, v in form_data.items(): | |
|
71 | setattr(new_users_group, k, v) | |
|
72 | ||
|
73 | self.sa.add(new_users_group) | |
|
74 | self.sa.commit() | |
|
75 | except: | |
|
76 | log.error(traceback.format_exc()) | |
|
77 | self.sa.rollback() | |
|
78 | raise | |
|
79 |
@@ -0,0 +1,55 b'' | |||
|
1 | ## -*- coding: utf-8 -*- | |
|
2 | <%inherit file="/base/base.html"/> | |
|
3 | ||
|
4 | <%def name="title()"> | |
|
5 | ${_('Add users 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(_('Users groups'),h.url('users_groups'))} | |
|
11 | » | |
|
12 | ${_('add new users 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('users_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('users_group_name',class_='small')} | |
|
36 | </div> | |
|
37 | </div> | |
|
38 | ||
|
39 | <div class="field"> | |
|
40 | <div class="label label-checkbox"> | |
|
41 | <label for="users_group_active">${_('Active')}:</label> | |
|
42 | </div> | |
|
43 | <div class="checkboxes"> | |
|
44 | ${h.checkbox('users_group_active',value=True)} | |
|
45 | </div> | |
|
46 | </div> | |
|
47 | ||
|
48 | <div class="buttons"> | |
|
49 | ${h.submit('save','save',class_="ui-button")} | |
|
50 | </div> | |
|
51 | </div> | |
|
52 | </div> | |
|
53 | ${h.end_form()} | |
|
54 | </div> | |
|
55 | </%def> No newline at end of file |
@@ -29,7 +29,6 b'' | |||
|
29 | 29 | <div class="table"> |
|
30 | 30 | <table class="table_disp"> |
|
31 | 31 | <tr class="header"> |
|
32 | <th></th> | |
|
33 | 32 | <th class="left">${_('group name')}</th> |
|
34 | 33 | <th class="left">${_('members')}</th> |
|
35 | 34 | <th class="left">${_('active')}</th> |
@@ -37,13 +36,13 b'' | |||
|
37 | 36 | </tr> |
|
38 | 37 | %for cnt,u_group in enumerate(c.users_groups_list): |
|
39 | 38 | <tr class="parity${cnt%2}"> |
|
40 | <td>${h.link_to(u_group.groupname,h.url('edit_user_group', id=u_group.group_id))}</td> | |
|
41 | <td>${u_group.members}</td> | |
|
42 | <td>${h.bool2icon(u_group.active)}</td> | |
|
39 | <td>${h.link_to(u_group.users_group_name,h.url('edit_users_group', id=u_group.users_group_id))}</td> | |
|
40 | <td>${len(u_group.members)}</td> | |
|
41 | <td>${h.bool2icon(u_group.users_group_active)}</td> | |
|
43 | 42 | <td> |
|
44 | ${h.form(url('users_group', id=group.group_id),method='delete')} | |
|
45 | ${h.submit('remove_','delete',id="remove_group_%s" % group.group_id, | |
|
46 | class_="delete_icon action_button",onclick="return confirm('Confirm to delete this user group');")} | |
|
43 | ${h.form(url('users_group', id=u_group.users_group_id),method='delete')} | |
|
44 | ${h.submit('remove_','delete',id="remove_group_%s" % u_group.users_group_id, | |
|
45 | class_="delete_icon action_button",onclick="return confirm('Confirm to delete this users group');")} | |
|
47 | 46 | ${h.end_form()} |
|
48 | 47 | </td> |
|
49 | 48 | </tr> |
General Comments 0
You need to be logged in to leave comments.
Login now