changeset 959:fff21c9b075c beta

#56 fixed found bugs, implemented adding of new group + forms+validators fixed db schema naming
author Marcin Kuzminski <marcin@python-works.com>
date Wed, 26 Jan 2011 17:34:37 +0100
parents 7d1483f3170b
children 029e69f0d21d
files rhodecode/config/routing.py rhodecode/controllers/admin/users_groups.py rhodecode/model/db.py rhodecode/model/forms.py rhodecode/model/user_group.py rhodecode/model/users_group.py rhodecode/templates/admin/users_groups/users_group_add.html rhodecode/templates/admin/users_groups/users_groups.html
diffstat 8 files changed, 221 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/config/routing.py	Tue Jan 25 23:28:10 2011 +0100
+++ b/rhodecode/config/routing.py	Wed Jan 26 17:34:37 2011 +0100
@@ -80,6 +80,10 @@
         m.connect('repo_cache', "/repos_cache/{repo_name:.*}",
              action="repo_cache", conditions=dict(method=["DELETE"],
                                                         function=check_repo))
+
+    #ADMIN USER REST ROUTES
+    map.resource('user', 'users', controller='admin/users', path_prefix='/_admin')
+
     #ADMIN USER REST ROUTES
     map.resource('users_group', 'users_groups', controller='admin/users_groups', path_prefix='/_admin')
 
--- a/rhodecode/controllers/admin/users_groups.py	Tue Jan 25 23:28:10 2011 +0100
+++ b/rhodecode/controllers/admin/users_groups.py	Wed Jan 26 17:34:37 2011 +0100
@@ -41,8 +41,9 @@
 from rhodecode.lib.base import BaseController, render
 
 from rhodecode.model.db import User, UsersGroup
-from rhodecode.model.forms import UserForm
+from rhodecode.model.forms import UserForm, UsersGroupForm
 from rhodecode.model.user import UserModel
+from rhodecode.model.users_group import UsersGroupModel
 
 log = logging.getLogger(__name__)
 
@@ -63,16 +64,38 @@
     def index(self, format='html'):
         """GET /users_groups: All items in the collection"""
         # url('users_groups')
-        c.users_groups_list = []
+        c.users_groups_list = self.sa.query(UsersGroup).all()
         return render('admin/users_groups/users_groups.html')
 
     def create(self):
         """POST /users_groups: Create a new item"""
         # url('users_groups')
+        users_group_model = UsersGroupModel()
+        users_group_form = UsersGroupForm()()
+        try:
+            form_result = users_group_form.to_python(dict(request.POST))
+            users_group_model.create(form_result)
+            h.flash(_('created users group %s') % form_result['users_group_name'],
+                    category='success')
+            #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa)
+        except formencode.Invalid, errors:
+            return htmlfill.render(
+                render('admin/users_groups/users_group_add.html'),
+                defaults=errors.value,
+                errors=errors.error_dict or {},
+                prefix_error=False,
+                encoding="UTF-8")
+        except Exception:
+            log.error(traceback.format_exc())
+            h.flash(_('error occurred during creation of users group %s') \
+                    % request.POST.get('users_group_name'), category='error')
+
+        return redirect(url('users_groups'))
 
     def new(self, format='html'):
         """GET /users_groups/new: Form to create a new item"""
         # url('new_users_group')
+        return render('admin/users_groups/users_group_add.html')
 
     def update(self, id):
         """PUT /users_groups/id: Update an existing item"""
--- a/rhodecode/model/db.py	Tue Jan 25 23:28:10 2011 +0100
+++ b/rhodecode/model/db.py	Wed Jan 26 17:34:37 2011 +0100
@@ -158,19 +158,18 @@
     __tablename__ = 'users_groups'
     __table_args__ = {'useexisting':True}
 
-    user_group_id = Column("users_groups_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    user_group_name = Column("user_group_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
-
+    users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
+    users_group_name = Column("users_group_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
+    users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
 
     members = relation('UsersGroupMember')
 
-
 class UsersGroupMember(Base, BaseModel):
     __tablename__ = 'users_groups_members'
     __table_args__ = {'useexisting':True}
 
-    user_groups_members_id = Column("user_groups_members_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_groups_id'), nullable=False, unique=None, default=None)
+    users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
+    users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
     user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
 
     user = relation('User')
@@ -257,7 +256,7 @@
     __tablename__ = 'users_group_to_perm'
     __table_args__ = (UniqueConstraint('users_group_id', 'permission_id'), {'useexisting':True})
     users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_groups_id'), nullable=False, unique=None, default=None)
+    users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
     permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 
     users_group = relation('UsersGroup')
--- a/rhodecode/model/forms.py	Tue Jan 25 23:28:10 2011 +0100
+++ b/rhodecode/model/forms.py	Wed Jan 26 17:34:37 2011 +0100
@@ -36,6 +36,7 @@
 from rhodecode.model import meta
 from rhodecode.model.user import UserModel
 from rhodecode.model.repo import RepoModel
+from rhodecode.model.users_group import UsersGroupModel
 from rhodecode.model.db import User
 from rhodecode import BACKENDS
 
@@ -88,6 +89,38 @@
 
     return _ValidUsername
 
+
+
+def ValidUsersGroup(edit, old_data):
+
+    class _ValidUsersGroup(formencode.validators.FancyValidator):
+
+        def validate_python(self, value, state):
+            if value in ['default']:
+                raise formencode.Invalid(_('Invalid group name'), value, state)
+            #check if group is unique
+            old_un = None
+            if edit:
+                old_un = UserModel().get(old_data.get('users_group_id')).username
+
+            if old_un != value or not edit:
+                if UsersGroupModel().get_by_groupname(value, cache=False,
+                                               case_insensitive=True):
+                    raise formencode.Invalid(_('This users group already exists') ,
+                                             value, state)
+
+
+            if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
+                raise formencode.Invalid(_('Group name may only contain '
+                                           'alphanumeric characters underscores, '
+                                           'periods or dashes and must begin with '
+                                           'alphanumeric character'),
+                                      value, state)
+
+    return _ValidUsersGroup
+
+
+
 class ValidPassword(formencode.validators.FancyValidator):
 
     def to_python(self, value, state):
@@ -368,6 +401,19 @@
 
     return _UserForm
 
+
+def UsersGroupForm(edit=False, old_data={}):
+    class _UsersGroupForm(formencode.Schema):
+        allow_extra_fields = True
+        filter_extra_fields = True
+
+        users_group_name = All(UnicodeString(strip=True, min=1, not_empty=True),
+                       ValidUsersGroup(edit, old_data))
+
+        users_group_active = StringBoolean(if_missing=False)
+
+    return _UsersGroupForm
+
 def RegisterForm(edit=False, old_data={}):
     class _RegisterForm(formencode.Schema):
         allow_extra_fields = True
--- a/rhodecode/model/user_group.py	Tue Jan 25 23:28:10 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-    rhodecode.model.user_group
-    ~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-    users groups model for RhodeCode
-    
-    :created_on: Jan 25, 2011
-    :author: marcink
-    :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>    
-    :license: GPLv3, see COPYING for more details.
-"""
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; version 2
-# of the License or (at your opinion) any later version of the license.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# MA  02110-1301, USA.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rhodecode/model/users_group.py	Wed Jan 26 17:34:37 2011 +0100
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+"""
+    rhodecode.model.user_group
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    users groups model for RhodeCode
+    
+    :created_on: Jan 25, 2011
+    :author: marcink
+    :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>    
+    :license: GPLv3, see COPYING for more details.
+"""
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; version 2
+# of the License or (at your opinion) any later version of the license.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.
+
+import logging
+import traceback
+
+from pylons.i18n.translation import _
+
+from rhodecode.model import BaseModel
+from rhodecode.model.caching_query import FromCache
+from rhodecode.model.db import UsersGroup
+
+from rhodecode.lib.exceptions import DefaultUserException, UserOwnsReposException
+
+from sqlalchemy.exc import DatabaseError
+
+log = logging.getLogger(__name__)
+
+
+class UsersGroupModel(BaseModel):
+
+    def get(self, users_group_id, cache=False):
+        users_group = self.sa.query(UsersGroup)
+        if cache:
+            users_group = users_group.options(FromCache("sql_cache_short",
+                                          "get_users_group_%s" % users_group_id))
+        return users_group.get(users_group_id)
+
+
+    def get_by_groupname(self, users_group_name, cache=False, case_insensitive=False):
+
+        if case_insensitive:
+            user = self.sa.query(UsersGroup)\
+            .filter(UsersGroup.users_group_name.ilike(users_group_name))
+        else:
+            user = self.sa.query(UsersGroup)\
+                .filter(UsersGroup.users_group_name == users_group_name)
+        if cache:
+            user = user.options(FromCache("sql_cache_short",
+                                          "get_user_%s" % users_group_name))
+        return user.scalar()
+
+    def create(self, form_data):
+        try:
+            new_users_group = UsersGroup()
+            for k, v in form_data.items():
+                setattr(new_users_group, k, v)
+
+            self.sa.add(new_users_group)
+            self.sa.commit()
+        except:
+            log.error(traceback.format_exc())
+            self.sa.rollback()
+            raise
+
--- a/rhodecode/templates/admin/users_groups/users_group_add.html	Tue Jan 25 23:28:10 2011 +0100
+++ b/rhodecode/templates/admin/users_groups/users_group_add.html	Wed Jan 26 17:34:37 2011 +0100
@@ -0,0 +1,55 @@
+## -*- coding: utf-8 -*-
+<%inherit file="/base/base.html"/>
+
+<%def name="title()">
+    ${_('Add users group')} - ${c.rhodecode_name}
+</%def>
+<%def name="breadcrumbs_links()">
+    ${h.link_to(_('Admin'),h.url('admin_home'))} 
+    &raquo; 
+    ${h.link_to(_('Users groups'),h.url('users_groups'))} 
+    &raquo;
+    ${_('add new users group')}
+</%def>
+
+<%def name="page_nav()">
+    ${self.menu('admin')}
+</%def>
+
+<%def name="main()">
+<div class="box">
+    <!-- box / title -->
+    <div class="title">
+        ${self.breadcrumbs()}       
+    </div>
+    <!-- end box / title -->
+    ${h.form(url('users_groups'))}
+    <div class="form">
+        <!-- fields -->
+        <div class="fields">
+             <div class="field">
+                <div class="label">
+                    <label for="users_group_name">${_('Group name')}:</label>
+                </div>
+                <div class="input">
+                    ${h.text('users_group_name',class_='small')}
+                </div>
+             </div>
+            
+             <div class="field">
+                <div class="label label-checkbox">
+                    <label for="users_group_active">${_('Active')}:</label>
+                </div>
+                <div class="checkboxes">
+                    ${h.checkbox('users_group_active',value=True)}
+                </div>
+             </div>
+            
+            <div class="buttons">
+              ${h.submit('save','save',class_="ui-button")}
+            </div>             
+        </div>
+    </div>
+    ${h.end_form()}
+</div>    
+</%def>    
\ No newline at end of file
--- a/rhodecode/templates/admin/users_groups/users_groups.html	Tue Jan 25 23:28:10 2011 +0100
+++ b/rhodecode/templates/admin/users_groups/users_groups.html	Wed Jan 26 17:34:37 2011 +0100
@@ -29,7 +29,6 @@
     <div class="table">
         <table class="table_disp">
         <tr class="header">
-            <th></th>
             <th class="left">${_('group name')}</th>
             <th class="left">${_('members')}</th>
             <th class="left">${_('active')}</th>
@@ -37,13 +36,13 @@
         </tr>
             %for cnt,u_group in enumerate(c.users_groups_list):
                 <tr class="parity${cnt%2}">
-                    <td>${h.link_to(u_group.groupname,h.url('edit_user_group', id=u_group.group_id))}</td>
-                    <td>${u_group.members}</td>
-                    <td>${h.bool2icon(u_group.active)}</td>
+                    <td>${h.link_to(u_group.users_group_name,h.url('edit_users_group', id=u_group.users_group_id))}</td>
+                    <td>${len(u_group.members)}</td>
+                    <td>${h.bool2icon(u_group.users_group_active)}</td>
                     <td>
-                        ${h.form(url('users_group', id=group.group_id),method='delete')}
-                            ${h.submit('remove_','delete',id="remove_group_%s" % group.group_id,
-                            class_="delete_icon action_button",onclick="return confirm('Confirm to delete this user group');")}
+                        ${h.form(url('users_group', id=u_group.users_group_id),method='delete')}
+                            ${h.submit('remove_','delete',id="remove_group_%s" % u_group.users_group_id,
+                            class_="delete_icon action_button",onclick="return confirm('Confirm to delete this users group');")}
                         ${h.end_form()}
                     </td>
                 </tr>