changeset 1266:a1bcfe58a1ab beta

Fixed #161 form saves the create repository permission. routing update for users to support second form posting. models updates
author Marcin Kuzminski <marcin@python-works.com>
date Mon, 18 Apr 2011 20:18:12 +0200
parents 08ac2c3ae810
children d534aff5e82a
files rhodecode/config/routing.py rhodecode/controllers/admin/permissions.py rhodecode/controllers/admin/users.py rhodecode/lib/db_manage.py rhodecode/model/db.py rhodecode/templates/admin/users/user_edit.html rhodecode/templates/admin/users/users.html rhodecode/templates/admin/users_groups/users_group_edit.html
diffstat 8 files changed, 159 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/config/routing.py	Sun Apr 17 16:26:40 2011 +0200
+++ b/rhodecode/config/routing.py	Mon Apr 18 20:18:12 2011 +0200
@@ -105,16 +105,42 @@
                   controller='admin/repos_groups', path_prefix='/_admin')
 
     #ADMIN USER REST ROUTES
-    rmap.resource('user', 'users', controller='admin/users',
-                  path_prefix='/_admin')
+    with rmap.submapper(path_prefix='/_admin', controller='admin/users') as m:
+        m.connect("users", "/users",
+                  action="create", conditions=dict(method=["POST"]))
+        m.connect("users", "/users",
+                  action="index", conditions=dict(method=["GET"]))
+        m.connect("formatted_users", "/users.{format}",
+                  action="index", conditions=dict(method=["GET"]))
+        m.connect("new_user", "/users/new",
+                  action="new", conditions=dict(method=["GET"]))
+        m.connect("formatted_new_user", "/users/new.{format}",
+                  action="new", conditions=dict(method=["GET"]))
+        m.connect("update_user", "/users/{id}",
+                  action="update", conditions=dict(method=["PUT"]))
+        m.connect("delete_user", "/users/{id}",
+                  action="delete", conditions=dict(method=["DELETE"]))
+        m.connect("edit_user", "/users/{id}/edit",
+                  action="edit", conditions=dict(method=["GET"]))
+        m.connect("formatted_edit_user",
+                  "/users/{id}.{format}/edit",
+                  action="edit", conditions=dict(method=["GET"]))
+        m.connect("user", "/users/{id}",
+                  action="show", conditions=dict(method=["GET"]))
+        m.connect("formatted_user", "/users/{id}.{format}",
+                  action="show", conditions=dict(method=["GET"]))
+
+        #EXTRAS USER ROUTES
+        m.connect("user_perm", "/users_perm/{id}",
+                  action="update_perm", conditions=dict(method=["PUT"]))
 
     #ADMIN USERS REST ROUTES
     rmap.resource('users_group', 'users_groups',
                   controller='admin/users_groups', path_prefix='/_admin')
 
     #ADMIN GROUP REST ROUTES
-    rmap.resource('group', 'groups', controller='admin/groups',
-                  path_prefix='/_admin')
+    rmap.resource('group', 'groups',
+                  controller='admin/groups', path_prefix='/_admin')
 
     #ADMIN PERMISSIONS REST ROUTES
     rmap.resource('permission', 'permissions',
@@ -124,6 +150,7 @@
     rmap.connect('ldap_settings', '/_admin/ldap',
                  controller='admin/ldap_settings', action='ldap_settings',
                  conditions=dict(method=["POST"]))
+
     rmap.connect('ldap_home', '/_admin/ldap',
                  controller='admin/ldap_settings')
 
--- a/rhodecode/controllers/admin/permissions.py	Sun Apr 17 16:26:40 2011 +0200
+++ b/rhodecode/controllers/admin/permissions.py	Mon Apr 18 20:18:12 2011 +0200
@@ -33,7 +33,6 @@
 from rhodecode.lib.base import BaseController, render
 from rhodecode.model.forms import LdapSettingsForm, DefaultPermissionsForm
 from rhodecode.model.permission import PermissionModel
-from rhodecode.model.settings import SettingsModel
 from rhodecode.model.user import UserModel
 import formencode
 import logging
--- a/rhodecode/controllers/admin/users.py	Sun Apr 17 16:26:40 2011 +0200
+++ b/rhodecode/controllers/admin/users.py	Mon Apr 18 20:18:12 2011 +0200
@@ -38,7 +38,7 @@
 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
 from rhodecode.lib.base import BaseController, render
 
-from rhodecode.model.db import User
+from rhodecode.model.db import User, RepoToPerm, UserToPerm, Permission
 from rhodecode.model.forms import UserForm
 from rhodecode.model.user import UserModel
 
@@ -101,7 +101,7 @@
         # Forms posted to this method should contain a hidden field:
         #    <input type="hidden" name="_method" value="PUT" />
         # Or using helpers:
-        #    h.form(url('user', id=ID),
+        #    h.form(url('update_user', id=ID),
         #           method='put')
         # url('user', id=ID)
         user_model = UserModel()
@@ -113,13 +113,16 @@
         try:
             form_result = _form.to_python(dict(request.POST))
             user_model.update(id, form_result)
-            h.flash(_('User updated succesfully'), category='success')
+            h.flash(_('User updated successfully'), category='success')
 
         except formencode.Invalid, errors:
+            e = errors.error_dict or {}
+            perm = Permission.get_by_key('hg.create.repository')
+            e.update({'create_repo_perm': UserToPerm.has_perm(id, perm)})
             return htmlfill.render(
                 render('admin/users/user_edit.html'),
                 defaults=errors.value,
-                errors=errors.error_dict or {},
+                errors=e,
                 prefix_error=False,
                 encoding="UTF-8")
         except Exception:
@@ -134,7 +137,7 @@
         # Forms posted to this method should contain a hidden field:
         #    <input type="hidden" name="_method" value="DELETE" />
         # Or using helpers:
-        #    h.form(url('user', id=ID),
+        #    h.form(url('delete_user', id=ID),
         #           method='delete')
         # url('user', id=ID)
         user_model = UserModel()
@@ -167,6 +170,8 @@
             .permissions['global']
 
         defaults = c.user.get_dict()
+        perm = Permission.get_by_key('hg.create.repository')
+        defaults.update({'create_repo_perm': UserToPerm.has_perm(id, perm)})
 
         return htmlfill.render(
             render('admin/users/user_edit.html'),
@@ -174,3 +179,29 @@
             encoding="UTF-8",
             force_defaults=False
         )
+
+    def update_perm(self, id):
+        """PUT /users_perm/id: Update an existing item"""
+        # url('user_perm', id=ID, method='put')
+
+        grant_perm = request.POST.get('create_repo_perm', False)
+
+        if grant_perm:
+            perm = Permission.get_by_key('hg.create.none')
+            UserToPerm.revoke_perm(id, perm)
+
+            perm = Permission.get_by_key('hg.create.repository')
+            UserToPerm.grant_perm(id, perm)
+            h.flash(_("Granted 'repository create' permission to user"),
+                    category='success')
+
+        else:
+            perm = Permission.get_by_key('hg.create.repository')
+            UserToPerm.revoke_perm(id, perm)
+
+            perm = Permission.get_by_key('hg.create.none')
+            UserToPerm.grant_perm(id, perm)
+            h.flash(_("Revoked 'repository create' permission to user"),
+                    category='success')
+
+        return redirect(url('edit_user', id=id))
--- a/rhodecode/lib/db_manage.py	Sun Apr 17 16:26:40 2011 +0200
+++ b/rhodecode/lib/db_manage.py	Mon Apr 18 20:18:12 2011 +0200
@@ -36,13 +36,14 @@
 from rhodecode.lib.auth import get_crypt_password, generate_api_key
 from rhodecode.lib.utils import ask_ok
 from rhodecode.model import init_model
-from rhodecode.model.db import User, Permission, RhodeCodeUi, RhodeCodeSettings, \
-    UserToPerm, DbMigrateVersion
+from rhodecode.model.db import User, Permission, RhodeCodeUi, \
+    RhodeCodeSettings, UserToPerm, DbMigrateVersion
 
 from sqlalchemy.engine import create_engine
 
 log = logging.getLogger(__name__)
 
+
 class DbManage(object):
     def __init__(self, log_sql, dbconf, root, tests=False):
         self.dbname = dbconf.split('/')[-1]
@@ -76,8 +77,6 @@
         meta.Base.metadata.create_all(checkfirst=checkfirst)
         log.info('Created tables for %s', self.dbname)
 
-
-
     def set_db_version(self):
         try:
             ver = DbMigrateVersion()
@@ -91,7 +90,6 @@
             raise
         log.info('db version set to: %s', __dbversion__)
 
-
     def upgrade(self):
         """Upgrades given database schema to given revision following
         all needed steps, to perform the upgrade
@@ -170,8 +168,6 @@
             print ('performing upgrade step %s' % step)
             callable = getattr(UpgradeSteps(self), 'step_%s' % step)()
 
-
-
     def fix_repo_paths(self):
         """Fixes a old rhodecode version path into new one without a '*'
         """
@@ -225,9 +221,9 @@
         if not self.tests:
             import getpass
 
-
             def get_password():
-                password = getpass.getpass('Specify admin password (min 6 chars):')
+                password = getpass.getpass('Specify admin password '
+                                           '(min 6 chars):')
                 confirm = getpass.getpass('Confirm password:')
 
                 if password != confirm:
@@ -252,9 +248,12 @@
             self.create_user(username, password, email, True)
         else:
             log.info('creating admin and regular test users')
-            self.create_user('test_admin', 'test12', 'test_admin@mail.com', True)
-            self.create_user('test_regular', 'test12', 'test_regular@mail.com', False)
-            self.create_user('test_regular2', 'test12', 'test_regular2@mail.com', False)
+            self.create_user('test_admin', 'test12',
+                             'test_admin@mail.com', True)
+            self.create_user('test_regular', 'test12',
+                             'test_regular@mail.com', False)
+            self.create_user('test_regular2', 'test12',
+                             'test_regular2@mail.com', False)
 
     def create_ui_settings(self):
         """Creates ui settings, fills out hooks
@@ -308,7 +307,6 @@
             self.sa.rollback()
             raise
 
-
     def create_ldap_options(self):
         """Creates ldap settings"""
 
@@ -321,7 +319,6 @@
                         ('ldap_attr_login', ''), ('ldap_attr_firstname', ''),
                         ('ldap_attr_lastname', ''), ('ldap_attr_email', '')]:
 
-
                 setting = RhodeCodeSettings(k, v)
                 self.sa.add(setting)
             self.sa.commit()
@@ -353,14 +350,12 @@
             log.error('No write permission to given path: %s [%s/3]',
                       path, retries)
 
-
         if retries == 0:
             sys.exit()
         if path_ok is False:
             retries -= 1
             return self.config_prompt(test_repo_path, retries)
 
-
         return path
 
     def create_settings(self, path):
@@ -393,12 +388,10 @@
         paths.ui_key = '/'
         paths.ui_value = path
 
-
         hgsettings1 = RhodeCodeSettings('realm', 'RhodeCode authentication')
         hgsettings2 = RhodeCodeSettings('title', 'RhodeCode')
         hgsettings3 = RhodeCodeSettings('ga_code', '')
 
-
         try:
             self.sa.add(web1)
             self.sa.add(web2)
@@ -467,8 +460,13 @@
                  ('hg.create.repository', 'Repository create'),
                  ('hg.create.none', 'Repository creation disabled'),
                  ('hg.register.none', 'Register disabled'),
-                 ('hg.register.manual_activate', 'Register new user with RhodeCode without manual activation'),
-                 ('hg.register.auto_activate', 'Register new user with RhodeCode without auto activation'),
+                 ('hg.register.manual_activate', 'Register new user with '
+                                                 'RhodeCode without manual'
+                                                 'activation'),
+
+                 ('hg.register.auto_activate', 'Register new user with '
+                                               'RhodeCode without auto '
+                                               'activation'),
                 ]
 
         for p in perms:
--- a/rhodecode/model/db.py	Sun Apr 17 16:26:40 2011 +0200
+++ b/rhodecode/model/db.py	Mon Apr 18 20:18:12 2011 +0200
@@ -33,7 +33,9 @@
 from sqlalchemy.orm import relationship, backref
 from sqlalchemy.orm.interfaces import MapperExtension
 
+from rhodecode.lib import str2bool
 from rhodecode.model.meta import Base, Session
+from rhodecode.model.caching_query import FromCache
 
 log = logging.getLogger(__name__)
 
@@ -61,6 +63,35 @@
         return "<%s('%s:%s')>" % (self.__class__.__name__,
                                   self.app_settings_name, self.app_settings_value)
 
+
+    @classmethod
+    def get_app_settings(cls, cache=False):
+
+        ret = Session.query(cls)
+
+        if cache:
+            ret = ret.options(FromCache("sql_cache_short", "get_hg_settings"))
+
+        if not ret:
+            raise Exception('Could not get application settings !')
+        settings = {}
+        for each in ret:
+            settings['rhodecode_' + each.app_settings_name] = \
+                each.app_settings_value
+
+        return settings
+
+    @classmethod
+    def get_ldap_settings(cls, cache=False):
+        ret = Session.query(cls)\
+                .filter(cls.app_settings_name.startswith('ldap_'))\
+                .all()
+        fd = {}
+        for row in ret:
+            fd.update({row.app_settings_name:str2bool(row.app_settings_value)})
+        return fd
+
+
 class RhodeCodeUi(Base):
     __tablename__ = 'rhodecode_ui'
     __table_args__ = {'useexisting':True}
@@ -285,6 +316,10 @@
         return "<%s('%s:%s')>" % (self.__class__.__name__,
                                   self.permission_id, self.permission_name)
 
+    @classmethod
+    def get_by_key(cls, key):
+        return Session.query(cls).filter(cls.permission_name == key).scalar()
+
 class RepoToPerm(Base):
     __tablename__ = 'repo_to_perm'
     __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True})
@@ -307,6 +342,40 @@
     user = relationship('User')
     permission = relationship('Permission')
 
+    @classmethod
+    def has_perm(cls, user_id, perm):
+        if not isinstance(perm, Permission):
+            raise Exception('perm needs to be an instance of Permission class')
+
+        return Session.query(cls).filter(cls.user_id == user_id)\
+            .filter(cls.permission == perm).scalar() is not None
+
+    @classmethod
+    def grant_perm(cls, user_id, perm):
+        if not isinstance(perm, Permission):
+            raise Exception('perm needs to be an instance of Permission class')
+
+        new = cls()
+        new.user_id = user_id
+        new.permission = perm
+        try:
+            Session.add(new)
+            Session.commit()
+        except:
+            Session.rollback()
+
+
+    @classmethod
+    def revoke_perm(cls, user_id, perm):
+        if not isinstance(perm, Permission):
+            raise Exception('perm needs to be an instance of Permission class')
+
+        try:
+            Session.query(cls).filter(cls.user_id == user_id)\
+                .filter(cls.permission == perm).delete()
+            Session.commit()
+        except:
+            Session.rollback()
 
 class UsersGroupToPerm(Base):
     __tablename__ = 'users_group_to_perm'
--- a/rhodecode/templates/admin/users/user_edit.html	Sun Apr 17 16:26:40 2011 +0200
+++ b/rhodecode/templates/admin/users/user_edit.html	Mon Apr 18 20:18:12 2011 +0200
@@ -24,7 +24,7 @@
         ${self.breadcrumbs()}       
     </div>
     <!-- end box / title -->
-    ${h.form(url('user', id=c.user.user_id),method='put')}
+    ${h.form(url('update_user', id=c.user.user_id),method='put')}
     <div class="form">
         <div class="field">
            <div class="gravatar_box">
@@ -126,7 +126,7 @@
     <div class="title">
         <h5>${_('Permissions')}</h5>       
     </div>
-    ${h.form(url('user', id=c.user.user_id),method='put')}
+    ${h.form(url('user_perm', id=c.user.user_id),method='put')}
     <div class="form">
         <!-- fields -->
         <div class="fields">
@@ -135,7 +135,7 @@
                     <label for="">${_('Create repositories')}:</label>
                 </div>
                 <div class="checkboxes">
-                    ${h.checkbox('create',value=True)}
+                    ${h.checkbox('create_repo_perm',value=True)}
                 </div>
              </div>
             <div class="buttons">
--- a/rhodecode/templates/admin/users/users.html	Sun Apr 17 16:26:40 2011 +0200
+++ b/rhodecode/templates/admin/users/users.html	Mon Apr 18 20:18:12 2011 +0200
@@ -51,7 +51,7 @@
                     <td>${h.bool2icon(user.admin)}</td>
                     <td>${h.bool2icon(bool(user.ldap_dn))}</td>
                     <td>
-                        ${h.form(url('user', id=user.user_id),method='delete')}
+                        ${h.form(url('delete_user', id=user.user_id),method='delete')}
                             ${h.submit('remove_','delete',id="remove_user_%s" % user.user_id,
                             class_="delete_icon action_button",onclick="return confirm('Confirm to delete this user');")}
                         ${h.end_form()}
--- a/rhodecode/templates/admin/users_groups/users_group_edit.html	Sun Apr 17 16:26:40 2011 +0200
+++ b/rhodecode/templates/admin/users_groups/users_group_edit.html	Mon Apr 18 20:18:12 2011 +0200
@@ -247,7 +247,7 @@
     <div class="title">
         <h5>${_('Permissions')}</h5>       
     </div>
-    ${h.form(url('user', id=''),method='put')}
+    ${h.form(url('xxx', id=''),method='put')}
     <div class="form">
         <!-- fields -->
         <div class="fields">